summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2012-05-03 00:11:50 -0500
committerMichael Merickel <michael@merickel.org>2012-05-03 00:11:50 -0500
commitc1c2b6ad8e22f9cba291de8903edfa4c7c741dca (patch)
treec3bfa436eafa3903af04a4f4f3750a7ddb216830
parentc3df7a76fa9f92201fbf57693b580b8904fac038 (diff)
parent004882434aa166a58c3b2148322e08ce61ec4cb7 (diff)
downloadpyramid-c1c2b6ad8e22f9cba291de8903edfa4c7c741dca.tar.gz
pyramid-c1c2b6ad8e22f9cba291de8903edfa4c7c741dca.tar.bz2
pyramid-c1c2b6ad8e22f9cba291de8903edfa4c7c741dca.zip
Merge branch 'master' into feature.json-api
-rw-r--r--CHANGES.txt13
-rw-r--r--TODO.txt9
-rw-r--r--docs/glossary.rst6
-rw-r--r--docs/narr/commandline.rst4
-rw-r--r--docs/narr/startup.rst14
-rw-r--r--docs/narr/urldispatch.rst2
-rw-r--r--docs/tutorials/wiki/installation.rst7
-rw-r--r--docs/tutorials/wiki2/installation.rst10
-rw-r--r--docs/tutorials/wiki2/src/authorization/development.ini2
-rw-r--r--docs/tutorials/wiki2/src/authorization/production.ini2
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/development.ini2
-rw-r--r--docs/tutorials/wiki2/src/basiclayout/production.ini2
-rw-r--r--docs/tutorials/wiki2/src/models/development.ini2
-rw-r--r--docs/tutorials/wiki2/src/models/production.ini2
-rw-r--r--docs/tutorials/wiki2/src/tests/development.ini2
-rw-r--r--docs/tutorials/wiki2/src/tests/production.ini2
-rw-r--r--docs/tutorials/wiki2/src/views/development.ini2
-rw-r--r--docs/tutorials/wiki2/src/views/production.ini2
-rw-r--r--pyramid/scaffolds/alchemy/README.txt_tmpl2
-rw-r--r--pyramid/scaffolds/alchemy/development.ini_tmpl2
-rw-r--r--pyramid/scaffolds/alchemy/production.ini_tmpl2
-rw-r--r--pyramid/scaffolds/alchemy/setup.py_tmpl2
-rw-r--r--pyramid/scaffolds/starter/setup.py_tmpl2
-rw-r--r--pyramid/scaffolds/zodb/setup.py_tmpl2
-rw-r--r--pyramid/static.py12
-rw-r--r--pyramid/tests/test_scaffolds/test_copydir.py6
-rw-r--r--pyramid/tests/test_static.py66
-rw-r--r--pyramid/tests/test_url.py17
-rw-r--r--pyramid/url.py8
-rw-r--r--setup.cfg2
-rw-r--r--setup.py21
31 files changed, 134 insertions, 95 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 337754162..34d60090d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,7 +9,6 @@ Bug Fixes
return the empty list. This was incorrect, it should have unconditionally
returned ``[Everyone]``, and now does.
-
Features
--------
@@ -21,7 +20,7 @@ Features
- As of this release, the ``request_method`` predicate, when used, will also
imply that ``HEAD`` is implied when you use ``GET``. For example, using
``@view_config(request_method='GET')`` is equivalent to using
- ``@view_config(request_method='HEAD')``. Using
+ ``@view_config(request_method=('GET', 'HEAD'))``. Using
``@view_config(request_method=('GET', 'POST')`` is equivalent to using
``@view_config(request_method=('GET', 'HEAD', 'POST')``. This is because
HEAD is a variant of GET that omits the body, and WebOb has special support
@@ -29,3 +28,13 @@ Features
- ``config.set_request_property`` now causes less code to be executed at
request construction time.
+
+- Don't add a ``?`` to URLs generated by request.resource_url if the
+ ``query`` argument is provided but empty.
+
+- Don't add a ``?`` to URLs generated by request.route_url if the
+ ``_query`` argument is provided but empty.
+
+- The static view machinery now raises (rather than returns) ``HTTPNotFound``
+ and ``HTTPMovedPermanently`` exceptions, so these can be caught by the
+ NotFound view (and other exception views).
diff --git a/TODO.txt b/TODO.txt
index e0fb0fa27..4b4f48499 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -4,6 +4,10 @@ Pyramid TODOs
Nice-to-Have
------------
+- config.set_registry_attr (with conflict detection).
+
+- _fix_registry should dictify the registry being fixed.
+
- Provide the presumed renderer name to the called view as an attribute of
the request.
@@ -67,8 +71,6 @@ Nice-to-Have
app1" and "domain app1.localhost = app1"), ProxyPreserveHost and the nginx
equivalent, preserving HTTPS URLs.
-- _fix_registry should dictify the registry being fixed.
-
- Make "localizer" a property of request (instead of requiring
"get_localizer(request)"?
@@ -126,6 +128,9 @@ Future
- 1.5: Remove ``pyramid.requests.DeprecatedRequestMethodsMixin``.
+- 1.5: Maybe? deprecate set_request_property in favor of pointing people at
+ set_request_method.
+
- 1.6: Remove IContextURL and TraversalContextURL.
Probably Bad Ideas
diff --git a/docs/glossary.rst b/docs/glossary.rst
index 88598354a..45a79326f 100644
--- a/docs/glossary.rst
+++ b/docs/glossary.rst
@@ -922,9 +922,9 @@ Glossary
http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/dev/ .
scaffold
- A project template that helps users get started writing a Pyramid
- application quickly. Scaffolds are usually used via the ``pcreate``
- command.
+ A project template that generates some of the major parts of a Pyramid
+ application and helps users to quickly get started writing larger
+ applications. Scaffolds are usually used via the ``pcreate`` command.
pyramid_exclog
A package which logs Pyramid application exception (error) information
diff --git a/docs/narr/commandline.rst b/docs/narr/commandline.rst
index 886e075e3..4be436836 100644
--- a/docs/narr/commandline.rst
+++ b/docs/narr/commandline.rst
@@ -460,7 +460,7 @@ to the console.
You can add request header values by using the ``--header`` option::
- $ bin/prequest --header=Host=example.com development.ini /
+ $ bin/prequest --header=Host:example.com development.ini /
Headers are added to the WSGI environment by converting them to their
CGI/WSGI equivalents (e.g. ``Host=example.com`` will insert the ``HTTP_HOST``
@@ -718,7 +718,7 @@ we'll pretend you have a distribution with a package in it named
def settings_show():
description = """\
Print the deployment settings for a Pyramid application. Example:
- 'psettings deployment.ini'
+ 'show_settings deployment.ini'
"""
usage = "usage: %prog config_uri"
parser = optparse.OptionParser(
diff --git a/docs/narr/startup.rst b/docs/narr/startup.rst
index 8e28835af..f5c741f52 100644
--- a/docs/narr/startup.rst
+++ b/docs/narr/startup.rst
@@ -42,8 +42,8 @@ Here's a high-level time-ordered overview of what happens when you press
``[pipeline:main]``, or ``[composite:main]`` in the ``.ini`` file. This
section represents the configuration of a :term:`WSGI` application that
will be served. If you're using a simple application (e.g.
- ``[app:main]``), the application :term:`entry point` or :term:`dotted
- Python name` will be named on the ``use=`` line within the section's
+ ``[app:main]``), the application's ``paste.app_factory`` :term:`entry
+ point` will be named on the ``use=`` line within the section's
configuration. If, instead of a simple application, you're using a WSGI
:term:`pipeline` (e.g. a ``[pipeline:main]`` section), the application
named on the "last" element will refer to your :app:`Pyramid` application.
@@ -59,11 +59,11 @@ Here's a high-level time-ordered overview of what happens when you press
system for this application. See :ref:`logging_config` for more
information.
-#. The application's *constructor* named by the entry point reference or
- dotted Python name on the ``use=`` line of the section representing your
- :app:`Pyramid` application is passed the key/value parameters mentioned
- within the section in which it's defined. The constructor is meant to
- return a :term:`router` instance, which is a :term:`WSGI` application.
+#. The application's *constructor* named by the entry point reference on the
+ ``use=`` line of the section representing your :app:`Pyramid` application
+ is passed the key/value parameters mentioned within the section in which
+ it's defined. The constructor is meant to return a :term:`router`
+ instance, which is a :term:`WSGI` application.
For :app:`Pyramid` applications, the constructor will be a function named
``main`` in the ``__init__.py`` file within the :term:`package` in which
diff --git a/docs/narr/urldispatch.rst b/docs/narr/urldispatch.rst
index f036ce94e..acbccbdfd 100644
--- a/docs/narr/urldispatch.rst
+++ b/docs/narr/urldispatch.rst
@@ -547,7 +547,7 @@ add to your application:
config.add_route('idea', 'ideas/{idea}')
config.add_route('user', 'users/{user}')
- config.add_route('tag', 'tags/{tags}')
+ config.add_route('tag', 'tags/{tag}')
config.add_view('mypackage.views.idea_view', route_name='idea')
config.add_view('mypackage.views.user_view', route_name='user')
diff --git a/docs/tutorials/wiki/installation.rst b/docs/tutorials/wiki/installation.rst
index 63b30da5a..868c99dee 100644
--- a/docs/tutorials/wiki/installation.rst
+++ b/docs/tutorials/wiki/installation.rst
@@ -130,9 +130,10 @@ Preparation, Windows
Make a Project
==============
-Your next step is to create a project. :app:`Pyramid` supplies a variety of
-scaffolds to generate sample projects. For this tutorial, we will use the
-:term:`ZODB` -oriented scaffold named ``zodb``.
+Your next step is to create a project. For this tutorial, we will use the
+:term:`scaffold` named ``zodb``, which generates an application
+that uses :term:`ZODB` and :term:`traversal`. :app:`Pyramid`
+supplies a variety of scaffolds to generate sample projects.
The below instructions assume your current working directory is the
"virtualenv" named "pyramidtut".
diff --git a/docs/tutorials/wiki2/installation.rst b/docs/tutorials/wiki2/installation.rst
index 4ee2728c2..6589a1557 100644
--- a/docs/tutorials/wiki2/installation.rst
+++ b/docs/tutorials/wiki2/installation.rst
@@ -67,10 +67,10 @@ Preparation, Windows
Making a Project
================
-Your next step is to create a project. :app:`Pyramid` supplies a
-variety of scaffolds to generate sample projects. We will use the
-``alchemy`` scaffold, which generates an application
-that uses :term:`SQLAlchemy` and :term:`URL dispatch`.
+Your next step is to create a project. For this tutorial, we will use the
+:term:`scaffold` named ``alchemy``, which generates an application
+that uses :term:`SQLAlchemy` and :term:`URL dispatch`. :app:`Pyramid`
+supplies a variety of scaffolds to generate sample projects.
The below instructions assume your current working directory is the
"virtualenv" named "pyramidtut".
@@ -254,7 +254,7 @@ The output to your console should be something like this::
2011-11-26 14:42:25,140 INFO [sqlalchemy.engine.base.Engine][MainThread]
COMMIT
-Success! You should now have a ``tutorial.db`` file in your current working
+Success! You should now have a ``tutorial.sqlite`` file in your current working
directory. This will be a SQLite database with a single table defined in it
(``models``).
diff --git a/docs/tutorials/wiki2/src/authorization/development.ini b/docs/tutorials/wiki2/src/authorization/development.ini
index 38738f3c6..eb2f878c5 100644
--- a/docs/tutorials/wiki2/src/authorization/development.ini
+++ b/docs/tutorials/wiki2/src/authorization/development.ini
@@ -10,7 +10,7 @@ pyramid.includes =
pyramid_debugtoolbar
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/authorization/production.ini b/docs/tutorials/wiki2/src/authorization/production.ini
index c4034abad..4684d2f7a 100644
--- a/docs/tutorials/wiki2/src/authorization/production.ini
+++ b/docs/tutorials/wiki2/src/authorization/production.ini
@@ -9,7 +9,7 @@ pyramid.default_locale_name = en
pyramid.includes =
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini
index 38738f3c6..eb2f878c5 100644
--- a/docs/tutorials/wiki2/src/basiclayout/development.ini
+++ b/docs/tutorials/wiki2/src/basiclayout/development.ini
@@ -10,7 +10,7 @@ pyramid.includes =
pyramid_debugtoolbar
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini
index c4034abad..4684d2f7a 100644
--- a/docs/tutorials/wiki2/src/basiclayout/production.ini
+++ b/docs/tutorials/wiki2/src/basiclayout/production.ini
@@ -9,7 +9,7 @@ pyramid.default_locale_name = en
pyramid.includes =
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/models/development.ini b/docs/tutorials/wiki2/src/models/development.ini
index 38738f3c6..eb2f878c5 100644
--- a/docs/tutorials/wiki2/src/models/development.ini
+++ b/docs/tutorials/wiki2/src/models/development.ini
@@ -10,7 +10,7 @@ pyramid.includes =
pyramid_debugtoolbar
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/models/production.ini b/docs/tutorials/wiki2/src/models/production.ini
index c4034abad..4684d2f7a 100644
--- a/docs/tutorials/wiki2/src/models/production.ini
+++ b/docs/tutorials/wiki2/src/models/production.ini
@@ -9,7 +9,7 @@ pyramid.default_locale_name = en
pyramid.includes =
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/tests/development.ini b/docs/tutorials/wiki2/src/tests/development.ini
index 38738f3c6..eb2f878c5 100644
--- a/docs/tutorials/wiki2/src/tests/development.ini
+++ b/docs/tutorials/wiki2/src/tests/development.ini
@@ -10,7 +10,7 @@ pyramid.includes =
pyramid_debugtoolbar
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/tests/production.ini b/docs/tutorials/wiki2/src/tests/production.ini
index c4034abad..4684d2f7a 100644
--- a/docs/tutorials/wiki2/src/tests/production.ini
+++ b/docs/tutorials/wiki2/src/tests/production.ini
@@ -9,7 +9,7 @@ pyramid.default_locale_name = en
pyramid.includes =
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/views/development.ini b/docs/tutorials/wiki2/src/views/development.ini
index 38738f3c6..eb2f878c5 100644
--- a/docs/tutorials/wiki2/src/views/development.ini
+++ b/docs/tutorials/wiki2/src/views/development.ini
@@ -10,7 +10,7 @@ pyramid.includes =
pyramid_debugtoolbar
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/docs/tutorials/wiki2/src/views/production.ini b/docs/tutorials/wiki2/src/views/production.ini
index c4034abad..4684d2f7a 100644
--- a/docs/tutorials/wiki2/src/views/production.ini
+++ b/docs/tutorials/wiki2/src/views/production.ini
@@ -9,7 +9,7 @@ pyramid.default_locale_name = en
pyramid.includes =
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/tutorial.db
+sqlalchemy.url = sqlite:///%(here)s/tutorial.sqlite
[server:main]
use = egg:waitress#main
diff --git a/pyramid/scaffolds/alchemy/README.txt_tmpl b/pyramid/scaffolds/alchemy/README.txt_tmpl
index efea71c5c..9e4aa1125 100644
--- a/pyramid/scaffolds/alchemy/README.txt_tmpl
+++ b/pyramid/scaffolds/alchemy/README.txt_tmpl
@@ -8,7 +8,7 @@ Getting Started
- $venv/bin/python setup.py develop
-- $venv/bin/populate_{{project}} development.ini
+- $venv/bin/initialize_{{project}}_db development.ini
- $venv/bin/pserve development.ini
diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl
index bcba06c1c..eebfbcc3e 100644
--- a/pyramid/scaffolds/alchemy/development.ini_tmpl
+++ b/pyramid/scaffolds/alchemy/development.ini_tmpl
@@ -10,7 +10,7 @@ pyramid.includes =
pyramid_debugtoolbar
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/{{project}}.db
+sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite
[server:main]
use = egg:waitress#main
diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl
index dc9145d12..9488f1811 100644
--- a/pyramid/scaffolds/alchemy/production.ini_tmpl
+++ b/pyramid/scaffolds/alchemy/production.ini_tmpl
@@ -9,7 +9,7 @@ pyramid.default_locale_name = en
pyramid.includes =
pyramid_tm
-sqlalchemy.url = sqlite:///%(here)s/{{project}}.db
+sqlalchemy.url = sqlite:///%(here)s/{{project}}.sqlite
[server:main]
use = egg:waitress#main
diff --git a/pyramid/scaffolds/alchemy/setup.py_tmpl b/pyramid/scaffolds/alchemy/setup.py_tmpl
index b80fc52a8..2d8ed028f 100644
--- a/pyramid/scaffolds/alchemy/setup.py_tmpl
+++ b/pyramid/scaffolds/alchemy/setup.py_tmpl
@@ -22,7 +22,7 @@ setup(name='{{project}}',
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/pyramid/scaffolds/starter/setup.py_tmpl b/pyramid/scaffolds/starter/setup.py_tmpl
index 39ac6de9d..58c0a79fc 100644
--- a/pyramid/scaffolds/starter/setup.py_tmpl
+++ b/pyramid/scaffolds/starter/setup.py_tmpl
@@ -18,7 +18,7 @@ setup(name='{{project}}',
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/pyramid/scaffolds/zodb/setup.py_tmpl b/pyramid/scaffolds/zodb/setup.py_tmpl
index 965c0178f..acdf095d5 100644
--- a/pyramid/scaffolds/zodb/setup.py_tmpl
+++ b/pyramid/scaffolds/zodb/setup.py_tmpl
@@ -21,7 +21,7 @@ setup(name='{{project}}',
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/pyramid/static.py b/pyramid/static.py
index dfb602ee0..63ca58597 100644
--- a/pyramid/static.py
+++ b/pyramid/static.py
@@ -101,17 +101,17 @@ class static_view(object):
path = _secure_path(path_tuple)
if path is None:
- return HTTPNotFound('Out of bounds: %s' % request.url)
+ raise HTTPNotFound('Out of bounds: %s' % request.url)
if self.package_name: # package resource
resource_path ='%s/%s' % (self.docroot.rstrip('/'), path)
if resource_isdir(self.package_name, resource_path):
if not request.path_url.endswith('/'):
- return self.add_slash_redirect(request)
+ self.add_slash_redirect(request)
resource_path = '%s/%s' % (resource_path.rstrip('/'),self.index)
if not resource_exists(self.package_name, resource_path):
- return HTTPNotFound(request.url)
+ raise HTTPNotFound(request.url)
filepath = resource_filename(self.package_name, resource_path)
else: # filesystem file
@@ -120,10 +120,10 @@ class static_view(object):
filepath = normcase(normpath(join(self.norm_docroot, path)))
if isdir(filepath):
if not request.path_url.endswith('/'):
- return self.add_slash_redirect(request)
+ self.add_slash_redirect(request)
filepath = join(filepath, self.index)
if not exists(filepath):
- return HTTPNotFound(request.url)
+ raise HTTPNotFound(request.url)
return FileResponse(filepath, request, self.cache_max_age)
@@ -132,7 +132,7 @@ class static_view(object):
qs = request.query_string
if qs:
url = url + '?' + qs
- return HTTPMovedPermanently(url)
+ raise HTTPMovedPermanently(url)
_seps = set(['/', os.sep])
def _contains_slash(item):
diff --git a/pyramid/tests/test_scaffolds/test_copydir.py b/pyramid/tests/test_scaffolds/test_copydir.py
index 42edd9d23..68cefbe6e 100644
--- a/pyramid/tests/test_scaffolds/test_copydir.py
+++ b/pyramid/tests/test_scaffolds/test_copydir.py
@@ -170,9 +170,11 @@ class Test_makedirs(unittest.TestCase):
def test_makedirs_parent_dir(self):
import shutil
- target = "/tmp/nonexistent_dir/nonexistent_subdir"
+ import tempfile
+ tmpdir = tempfile.mkdtemp()
+ target = os.path.join(tmpdir, 'nonexistent_subdir')
self._callFUT(target, 2, None)
- shutil.rmtree("/tmp/nonexistent_dir")
+ shutil.rmtree(tmpdir)
class Test_support_functions(unittest.TestCase):
diff --git a/pyramid/tests/test_static.py b/pyramid/tests/test_static.py
index 7f94df990..94497d4f6 100644
--- a/pyramid/tests/test_static.py
+++ b/pyramid/tests/test_static.py
@@ -38,11 +38,9 @@ class Test_static_view_use_subpath_False(unittest.TestCase):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest({'PATH_INFO':''})
context = DummyContext()
- response = inst(context, request)
- response.prepare(request.environ)
- self.assertEqual(response.status, '301 Moved Permanently')
- self.assertTrue(b'http://example.com:6543/' in response.body)
-
+ from pyramid.httpexceptions import HTTPMovedPermanently
+ self.assertRaises(HTTPMovedPermanently, inst, context, request)
+
def test_path_info_slash_means_index_html(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest()
@@ -70,16 +68,16 @@ class Test_static_view_use_subpath_False(unittest.TestCase):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest({'PATH_INFO':'/subdir/../../minimal.pt'})
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_oob_dotdotslash_encoded(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest(
{'PATH_INFO':'/subdir/%2E%2E%2F%2E%2E/minimal.pt'})
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_oob_os_sep(self):
import os
@@ -88,15 +86,15 @@ class Test_static_view_use_subpath_False(unittest.TestCase):
request = self._makeRequest({'PATH_INFO':'/subdir/%s%sminimal.pt' %
(dds, dds)})
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_resource_doesnt_exist(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest({'PATH_INFO':'/notthere'})
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_resource_isdir(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
@@ -174,8 +172,8 @@ class Test_static_view_use_subpath_False(unittest.TestCase):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest({'PATH_INFO':'/notthere.html'})
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_resource_with_content_encoding(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
@@ -233,11 +231,9 @@ class Test_static_view_use_subpath_True(unittest.TestCase):
request = self._makeRequest({'PATH_INFO':''})
request.subpath = ()
context = DummyContext()
- response = inst(context, request)
- response.prepare(request.environ)
- self.assertEqual(response.status, '301 Moved Permanently')
- self.assertTrue(b'http://example.com:6543/' in response.body)
-
+ from pyramid.httpexceptions import HTTPMovedPermanently
+ self.assertRaises(HTTPMovedPermanently, inst, context, request)
+
def test_path_info_slash_means_index_html(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest()
@@ -251,33 +247,33 @@ class Test_static_view_use_subpath_True(unittest.TestCase):
request = self._makeRequest()
request.subpath = ('.', 'index.html')
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_oob_emptyelement(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest()
request.subpath = ('', 'index.html')
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_oob_dotdotslash(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest()
request.subpath = ('subdir', '..', '..', 'minimal.pt')
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_oob_dotdotslash_encoded(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest()
request.subpath = ('subdir', '%2E%2E', '%2E%2E', 'minimal.pt')
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
-
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
+
def test_oob_os_sep(self):
import os
inst = self._makeOne('pyramid.tests:fixtures/static')
@@ -285,16 +281,16 @@ class Test_static_view_use_subpath_True(unittest.TestCase):
request = self._makeRequest()
request.subpath = ('subdir', dds, dds, 'minimal.pt')
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_resource_doesnt_exist(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
request = self._makeRequest()
request.subpath = ('notthere,')
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
def test_resource_isdir(self):
inst = self._makeOne('pyramid.tests:fixtures/static')
@@ -361,8 +357,8 @@ class Test_static_view_use_subpath_True(unittest.TestCase):
request = self._makeRequest()
request.subpath = ('notthere.html',)
context = DummyContext()
- response = inst(context, request)
- self.assertEqual(response.status, '404 Not Found')
+ from pyramid.httpexceptions import HTTPNotFound
+ self.assertRaises(HTTPNotFound, inst, context, request)
class DummyContext:
pass
diff --git a/pyramid/tests/test_url.py b/pyramid/tests/test_url.py
index 0dff1e648..50deb63f3 100644
--- a/pyramid/tests/test_url.py
+++ b/pyramid/tests/test_url.py
@@ -113,6 +113,14 @@ class TestURLMethodsMixin(unittest.TestCase):
self.assertEqual(result,
'http://example.com:5432/context/a?a=hi+there&b=La+Pe%C3%B1a')
+ def test_resource_url_with_query_empty(self):
+ request = self._makeOne()
+ self._registerResourceURL(request.registry)
+ context = DummyContext()
+ result = request.resource_url(context, 'a', query=[])
+ self.assertEqual(result,
+ 'http://example.com:5432/context/a')
+
def test_resource_url_anchor_is_after_root_when_no_elements(self):
request = self._makeOne()
self._registerResourceURL(request.registry)
@@ -334,6 +342,15 @@ class TestURLMethodsMixin(unittest.TestCase):
self.assertEqual(result,
'http://example.com:5432/1/2/3?q=1')
+ def test_route_url_with_empty_query(self):
+ from pyramid.interfaces import IRoutesMapper
+ request = self._makeOne()
+ mapper = DummyRoutesMapper(route=DummyRoute('/1/2/3'))
+ request.registry.registerUtility(mapper, IRoutesMapper)
+ result = request.route_url('flub', _query={})
+ self.assertEqual(result,
+ 'http://example.com:5432/1/2/3')
+
def test_route_url_with_app_url(self):
from pyramid.interfaces import IRoutesMapper
request = self._makeOne()
diff --git a/pyramid/url.py b/pyramid/url.py
index 022867967..dd83bb631 100644
--- a/pyramid/url.py
+++ b/pyramid/url.py
@@ -218,7 +218,9 @@ class URLMethodsMixin(object):
port = None
if '_query' in kw:
- qs = '?' + urlencode(kw.pop('_query'), doseq=True)
+ query = kw.pop('_query')
+ if query:
+ qs = '?' + urlencode(query, doseq=True)
if '_anchor' in kw:
anchor = kw.pop('_anchor')
@@ -494,7 +496,9 @@ class URLMethodsMixin(object):
anchor = ''
if 'query' in kw:
- qs = '?' + urlencode(kw['query'], doseq=True)
+ query = kw['query']
+ if query:
+ qs = '?' + urlencode(query, doseq=True)
if 'anchor' in kw:
anchor = kw['anchor']
diff --git a/setup.cfg b/setup.cfg
index 8aac0afd1..d7622683f 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -10,4 +10,4 @@ cover-erase=1
[aliases]
dev = develop easy_install pyramid[testing]
-
+docs = develop easy_install pyramid[docs]
diff --git a/setup.py b/setup.py
index e325b8a29..cbc1075bd 100644
--- a/setup.py
+++ b/setup.py
@@ -50,18 +50,22 @@ install_requires=[
tests_require = [
'WebTest >= 1.3.1', # py3 compat
- 'virtualenv',
]
if not PY3:
- tests_require.extend([
- 'Sphinx',
- 'docutils',
- 'repoze.sphinx.autointerface',
- 'zope.component>=3.11.0',
- ])
+ tests_require.append('zope.component>=3.11.0')
-testing_extras = tests_require + ['nose', 'coverage']
+docs_extras = [
+ 'Sphinx',
+ 'docutils',
+ 'repoze.sphinx.autointerface',
+ ]
+
+testing_extras = tests_require + [
+ 'nose',
+ 'coverage',
+ 'virtualenv', # for scaffolding tests
+ ]
setup(name='pyramid',
version='1.4dev',
@@ -93,6 +97,7 @@ setup(name='pyramid',
install_requires = install_requires,
extras_require = {
'testing':testing_extras,
+ 'docs':docs_extras,
},
tests_require = tests_require,
test_suite="pyramid.tests",