diff options
| author | Chris McDonough <chrism@plope.com> | 2014-05-05 23:56:09 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2014-05-05 23:56:09 -0400 |
| commit | 7423971bf8aaa5fd205778820d91a6c7e3cea1bd (patch) | |
| tree | 35130316c871ff0d8c41c3ad57a5f5cc1d876c7c | |
| parent | 7a6bf6f0ff1b85d0158ad49fc21037db4999c1cf (diff) | |
| parent | f9bc568657f316f20b5f576085472b80dec15cba (diff) | |
| download | pyramid-7423971bf8aaa5fd205778820d91a6c7e3cea1bd.tar.gz pyramid-7423971bf8aaa5fd205778820d91a6c7e3cea1bd.tar.bz2 pyramid-7423971bf8aaa5fd205778820d91a6c7e3cea1bd.zip | |
fix merge conflicts
37 files changed, 273 insertions, 102 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index da8db870f..2b80e87e2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,17 @@ Next release ============ +Bug Fixes +--------- + +- ``pyramid.wsgi.wsgiapp`` and ``pyramid.wsgi.wsgiapp2`` now raise + ``ValueError`` when accidentally passed ``None``. + +- Fix an issue whereby predicates would be resolved as maybe_dotted in the + introspectable but not when passed for registration. This would mean that + add_route_predicate for example can not take a string and turn it into the + actual callable function. + Docs ---- @@ -8,6 +19,17 @@ Docs scaffolding- and logging-related chapters to avoid needing to explain it too early. +- Clarify a previously-implied detail of the ``ISession.invalidate`` API + documentation. + +Scaffolds +--------- + +- Update scaffold generating machinery to return the version of pyramid and + pyramid docs for use in scaffolds. Updated starter, alchemy and zodb + templates to have links to correctly versioned documentation and reflect + which pyramid was used to generate the scaffold. + 1.5 (2014-04-08) ================ diff --git a/HACKING.txt b/HACKING.txt index 460d02047..1386be3af 100644 --- a/HACKING.txt +++ b/HACKING.txt @@ -31,7 +31,7 @@ By Hand $ cd hack-on-pyramid # Configure remotes such that you can pull changes from the Pyramid # repository into your local repository. - $ git remote add upstream git@github.com:Pylons/pyramid.git + $ git remote add upstream https://github.com:Pylons/pyramid.git # fetch and merge changes from upstream into master $ git fetch upstream $ git merge upstream/master @@ -149,7 +149,7 @@ Coding Style ------------ - PEP8 compliance. Whitespace rules are relaxed: not necessary to put - 2 newlines between classes. But 80-column lines, in particular, are + 2 newlines between classes. But 79-column lines, in particular, are mandatory. See http://docs.pylonsproject.org/en/latest/community/codestyle.html for more information. diff --git a/docs/api/request.rst b/docs/api/request.rst index 343d0c022..77d80f6d6 100644 --- a/docs/api/request.rst +++ b/docs/api/request.rst @@ -319,7 +319,13 @@ def _connect(request): conn = request.registry.dbsession() - def cleanup(_): + def cleanup(request): + # since version 1.5, request.exception is no + # longer eagerly cleared + if request.exception is not None: + conn.rollback() + else: + conn.commit() conn.close() request.add_finished_callback(cleanup) return conn diff --git a/docs/conf.py b/docs/conf.py index eba776628..4bc8e2172 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -57,8 +57,9 @@ extensions = [ # Looks for objects in external projects intersphinx_mapping = { - 'tutorials': ('http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/', None), - 'jinja2': ('http://docs.pylonsproject.org/projects/pyramid_jinja2/en/latest/', None), + 'tutorials': ('http://docs.pylonsproject.org/projects/pyramid-tutorials/en/latest/', None), + 'cookbook': ('http://docs.pylonsproject.org/projects/pyramid-cookbook/en/latest/', None), + 'jinja2': ('http://docs.pylonsproject.org/projects/pyramid-jinja2/en/latest/', None), 'tm': ( 'http://docs.pylonsproject.org/projects/pyramid_tm/en/latest/', None, @@ -82,10 +83,10 @@ intersphinx_mapping = { 'venusian': ('http://docs.pylonsproject.org/projects/venusian/en/latest', None), 'toolbar': - ('http://docs.pylonsproject.org/projects/pyramid_debugtoolbar/en/latest', + ('http://docs.pylonsproject.org/projects/pyramid-debugtoolbar/en/latest', None), 'zcml': - ('http://docs.pylonsproject.org/projects/pyramid_zcml/en/latest', + ('http://docs.pylonsproject.org/projects/pyramid-zcml/en/latest', None), } diff --git a/docs/glossary.rst b/docs/glossary.rst index 2cc461a77..deb4c1c8b 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -936,7 +936,7 @@ Glossary `Akhet <http://docs.pylonsproject.org/projects/akhet/en/latest/>`_ is a Pyramid library and demo application with a Pylons-like feel. It's most known for its former application scaffold, which helped - users transition from Pylons and those prefering a more Pylons-like API. + users transition from Pylons and those preferring a more Pylons-like API. The scaffold has been retired but the demo plays a similar role. Pyramid Cookbook diff --git a/docs/index.rst b/docs/index.rst index 78a00966d..ac16ff237 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -119,6 +119,8 @@ Narrative documentation in chapter form explaining how to use narr/threadlocals narr/zca +.. _html_tutorials: + Tutorials ========= diff --git a/docs/narr/configuration.rst b/docs/narr/configuration.rst index f7a69d613..52615533d 100644 --- a/docs/narr/configuration.rst +++ b/docs/narr/configuration.rst @@ -114,7 +114,6 @@ in a package and its subpackages. For example: return Response('Hello') if __name__ == '__main__': - from pyramid.config import Configurator config = Configurator() config.scan() app = config.make_wsgi_app() diff --git a/docs/narr/install.rst b/docs/narr/install.rst index e419a8b20..a825b61b9 100644 --- a/docs/narr/install.rst +++ b/docs/narr/install.rst @@ -15,8 +15,8 @@ You will need `Python <http://python.org>`_ version 2.6 or better to run .. sidebar:: Python Versions As of this writing, :app:`Pyramid` has been tested under Python 2.6, Python - 2.7, Python 3.2, and Python 3.3. :app:`Pyramid` does not run under any - version of Python before 2.6. + 2.7, Python 3.2, Python 3.3, Python 3.4 and PyPy 2.2. :app:`Pyramid` does + not run under any version of Python before 2.6. :app:`Pyramid` is known to run on all popular UNIX-like systems such as Linux, Mac OS X, and FreeBSD as well as on Windows platforms. It is also known to run @@ -32,20 +32,22 @@ dependency will fall back to using pure Python instead. For Mac OS X Users ~~~~~~~~~~~~~~~~~~ -From `Python.org <http://python.org/download/mac/>`_: +Python comes pre-installed on Mac OS X, but due to Apple's release cycle, +it is often out of date. Unless you have a need for a specific earlier version, +it is recommended to install the latest 2.x or 3.x version of Python. - Python comes pre-installed on Mac OS X, but due to Apple's release cycle, - it's often one or even two years old. The overwhelming recommendation of - the "MacPython" community is to upgrade your Python by downloading and - installing a newer version from `the Python standard release page - <http://python.org/download/releases/>`_. +You can install the latest verion of Python for Mac OS X from the binaries on +`python.org <https://www.python.org/download/mac/>`_. -It is recommended to download one of the *installer* versions, unless you -prefer to install your Python through a packgage manager (e.g., macports or -homebrew) or to build your Python from source. +Alternatively, you can use the `homebrew <http://brew.sh/>`_ package manager. -Unless you have a need for a specific earlier version, it is recommended to -install the latest 2.x or 3.x version of Python. +.. code-block:: text + + # for python 2.7 + $ brew install python + + # for python 3.4 + $ brew install python3 If you use an installer for your Python, then you can skip to the section :ref:`installing_unix`. diff --git a/docs/narr/viewconfig.rst b/docs/narr/viewconfig.rst index adc53bd11..a0feef8d7 100644 --- a/docs/narr/viewconfig.rst +++ b/docs/narr/viewconfig.rst @@ -295,11 +295,14 @@ configured view. *This is an advanced feature, not often used by "civilians"*. ``request_method`` - This value can be a string (typically ``"GET"``, ``"POST"``, ``"PUT"``, - ``"DELETE"``, or ``"HEAD"``) representing an HTTP ``REQUEST_METHOD``. A view - declaration with this argument ensures that the view will only be called - when the request's ``method`` attribute (aka the ``REQUEST_METHOD`` of the - WSGI environment) string matches the supplied value. + This value can be either a string (such as ``"GET"``, ``"POST"``, + ``"PUT"``, ``"DELETE"``, ``"HEAD"`` or ``"OPTIONS"``) representing an + HTTP ``REQUEST_METHOD``, or a tuple containing one or more of these + strings. A view declaration with this argument ensures that the + view will only be called when the ``method`` attribute of the + request (aka the ``REQUEST_METHOD`` of the WSGI environment) matches + a supplied value. Note that use of ``"GET"`` also implies that the + view will respond to ``"HEAD"`` as of Pyramid 1.4. If ``request_method`` is not supplied, the view will be invoked regardless of the ``REQUEST_METHOD`` of the :term:`WSGI` environment. diff --git a/docs/narr/webob.rst b/docs/narr/webob.rst index f0a4b5a0b..6a331e4bf 100644 --- a/docs/narr/webob.rst +++ b/docs/narr/webob.rst @@ -408,6 +408,8 @@ Here are some highlights: The content type *not* including the ``charset`` parameter. Typical use: ``response.content_type = 'text/html'``. + Default value: ``response.content_type = 'text/html'``. + ``response.charset``: The ``charset`` parameter of the content-type, it also informs encoding in ``response.unicode_body``. @@ -466,9 +468,12 @@ argument to the class; e.g.: from pyramid.response import Response response = Response(body='hello world!', content_type='text/plain') -The status defaults to ``'200 OK'``. The content_type does not default to -anything, though if you subclass :class:`pyramid.response.Response` and set -``default_content_type`` you can override this behavior. +The status defaults to ``'200 OK'``. + +The value of content_type defaults to +``webob.response.Response.default_content_type``; which is `text/html`. +You can subclass :class:`pyramid.response.Response` and set +``default_content_type`` to override this behavior. .. index:: single: exception responses diff --git a/docs/quick_tour/views/views.py b/docs/quick_tour/views/views.py index 9dc795f14..1449cbb38 100644 --- a/docs/quick_tour/views/views.py +++ b/docs/quick_tour/views/views.py @@ -1,3 +1,5 @@ +import cgi + from pyramid.httpexceptions import HTTPFound from pyramid.response import Response from pyramid.view import view_config @@ -14,7 +16,8 @@ def home_view(request): def hello_view(request): name = request.params.get('name', 'No Name') body = '<p>Hi %s, this <a href="/goto">redirects</a></p>' - return Response(body % name) + # cgi.escape to prevent Cross-Site Scripting (XSS) [CWE 79] + return Response(body % cgi.escape(name)) # /goto which issues HTTP redirect to the last view @@ -23,7 +26,7 @@ def redirect_view(request): return HTTPFound(location="/problem") -# /problem which causes an site error +# /problem which causes a site error @view_config(route_name='exception') def exception_view(request): raise Exception() diff --git a/docs/quick_tutorial/debugtoolbar.rst b/docs/quick_tutorial/debugtoolbar.rst index 1c540d8a2..90750c633 100644 --- a/docs/quick_tutorial/debugtoolbar.rst +++ b/docs/quick_tutorial/debugtoolbar.rst @@ -71,16 +71,17 @@ supports wiring in add-on configuration via our ``development.ini`` using ``pyramid.includes``. We use this to load the configuration for the debugtoolbar. -You'll now see an attractive (and collapsible) menu in the right of -your browser, providing introspective access to debugging information. -Even better, if your web application generates an error, +You'll now see an attractive button on the right side of +your browser, which you may click to provide introspective access to debugging +information in a new browser tab. Even better, if your web application +generates an error, you will see a nice traceback on the screen. When you want to disable this toolbar, no need to change code: you can remove it from ``pyramid.includes`` in the relevant ``.ini`` configuration file (thus showing why configuration files are handy.) -Note that the toolbar mutates the HTML generated by our app and uses jQuery to -overlay itself. If you are using the toolbar while you're developing and you +Note injects a small amount of html/css into your app just before the closing +``</body>`` tag in order to display itself. If you start to experience otherwise inexplicable client-side weirdness, you can shut it off by commenting out the ``pyramid_debugtoolbar`` line in ``pyramid.includes`` temporarily. diff --git a/docs/quick_tutorial/jinja2.rst b/docs/quick_tutorial/jinja2.rst index 44d9f635b..2f1e295dd 100644 --- a/docs/quick_tutorial/jinja2.rst +++ b/docs/quick_tutorial/jinja2.rst @@ -88,9 +88,9 @@ Extra Credit dependency manually. What is another way we could have made the association? -#. We used ``development.ini`` to get the :term:`configurator` to - load ``pyramid_jinja2``'s configuration. What is another way could - include it into the config? +#. We used ``config.include`` which is an imperative configuration to get the + :term:`Configurator` to load ``pyramid_jinja2``'s configuration. + What is another way could include it into the config? .. seealso:: `Jinja2 homepage <http://jinja.pocoo.org/>`_, and diff --git a/docs/quick_tutorial/json.rst b/docs/quick_tutorial/json.rst index ece8a61c0..aa789d833 100644 --- a/docs/quick_tutorial/json.rst +++ b/docs/quick_tutorial/json.rst @@ -40,7 +40,7 @@ Steps :linenos: #. Rather than implement a new view, we will "stack" another decorator - on the ``hello`` view: + on the ``hello`` view in ``views.py``: .. literalinclude:: json/tutorial/views.py :linenos: diff --git a/docs/quick_tutorial/more_view_classes.rst b/docs/quick_tutorial/more_view_classes.rst index 1e5603554..9cc4cc520 100644 --- a/docs/quick_tutorial/more_view_classes.rst +++ b/docs/quick_tutorial/more_view_classes.rst @@ -34,7 +34,7 @@ that determine which view is matched to a request, based on factors such as the request method, the form parameters, etc. These predicates provide many axes of flexibility. -The following shows a simple example with four operations operations: +The following shows a simple example with four operations: view a home page which leads to a form, save a change, and press the delete button. diff --git a/docs/quick_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst index 72bb4a4f8..b5778ea42 100644 --- a/docs/quick_tutorial/requirements.rst +++ b/docs/quick_tutorial/requirements.rst @@ -187,9 +187,15 @@ pipe it to your environment's version of Python. $ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | $VENV/bin/python # Windows - # Use your browser to download: - # https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.p - # ...into c:\projects\quick_tutorial\ez_setup.py + # + # Use your web browser to download this file: + # https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py + # + # ...and save it to: + # c:\projects\quick_tutorial\ez_setup.py + # + # Then run the following command: + c:\> %VENV%\Scripts\python ez_setup.py If ``wget`` complains with a certificate error, then run this command instead: diff --git a/docs/quick_tutorial/sessions.rst b/docs/quick_tutorial/sessions.rst index 0f284e9a7..b4887beb8 100644 --- a/docs/quick_tutorial/sessions.rst +++ b/docs/quick_tutorial/sessions.rst @@ -13,10 +13,10 @@ When people use your web application, they frequently perform a task that requires semi-permanent data to be saved. For example, a shopping cart. This is called a :term:`session`. -Pyramid has basic built-in support for sessions, with add-ons -or your own custom sessioning engine) that can provide -richer session support. Let's take a look at the -:ref:`built-in sessioning support <sessions_chapter>`. +Pyramid has basic built-in support for sessions. Third party packages such as +``pyramid_redis_sessions`` provide richer session support. Or you can create +your own custom sessioning engine. Let's take a look at the +:doc:`built-in sessioning support <../narr/sessions>`. Objectives ========== diff --git a/docs/whatsnew-1.5.rst b/docs/whatsnew-1.5.rst index 65e8393f8..1d863c937 100644 --- a/docs/whatsnew-1.5.rst +++ b/docs/whatsnew-1.5.rst @@ -384,9 +384,9 @@ Other Backwards Incompatibilities are now "reified" properties that look up a locale name and localizer respectively using the machinery described in :ref:`i18n_chapter`. -- If you send an ``X-Vhm-Root`` header with a value that ends with a slash (or - any number of slashes), the trailing slash(es) will be removed before a URL - is generated when you use use :meth:`~pyramid.request.Request.resource_url` +- If you send an ``X-Vhm-Root`` header with a value that ends with any number + of slashes, the trailing slashes will be removed before the URL + is generated when you use :meth:`~pyramid.request.Request.resource_url` or :meth:`~pyramid.request.Request.resource_path`. Previously the virtual root path would not have trailing slashes stripped, which would influence URL generation. diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index 32cf82fba..ebaae38a9 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -481,6 +481,7 @@ class Configurator( def _add_predicate(self, type, name, factory, weighs_more_than=None, weighs_less_than=None): + factory = self.maybe_dotted(factory) discriminator = ('%s predicate' % type, name) intr = self.introspectable( '%s predicates' % type, @@ -488,7 +489,7 @@ class Configurator( '%s predicate named %s' % (type, name), '%s predicate' % type) intr['name'] = name - intr['factory'] = self.maybe_dotted(factory) + intr['factory'] = factory intr['weighs_more_than'] = weighs_more_than intr['weighs_less_than'] = weighs_less_than def register(): diff --git a/pyramid/config/views.py b/pyramid/config/views.py index 2f6c758ab..7a6157ec8 100644 --- a/pyramid/config/views.py +++ b/pyramid/config/views.py @@ -879,11 +879,11 @@ class ViewsConfiguratorMixin(object): request_method - This value can be either a strings (such as ``GET``, ``POST``, - ``PUT``, ``DELETE``, or ``HEAD``) representing an HTTP - ``REQUEST_METHOD``, or a tuple containing one or more of these - strings. A view declaration with this argument ensures that the - view will only be called when the ``method`` attribute of the + This value can be either a string (such as ``"GET"``, ``"POST"``, + ``"PUT"``, ``"DELETE"``, ``"HEAD"`` or ``"OPTIONS"``) representing + an HTTP ``REQUEST_METHOD``, or a tuple containing one or more of + these strings. A view declaration with this argument ensures that + the view will only be called when the ``method`` attribute of the request (aka the ``REQUEST_METHOD`` of the WSGI environment) matches a supplied value. Note that use of ``GET`` also implies that the view will respond to ``HEAD`` as of Pyramid 1.4. diff --git a/pyramid/interfaces.py b/pyramid/interfaces.py index 75b9b1cb9..aa2dbdafd 100644 --- a/pyramid/interfaces.py +++ b/pyramid/interfaces.py @@ -910,7 +910,13 @@ class ISession(IDict): ``invalidate`` is implementation-dependent, but it should have the effect of completely dissociating any data stored in the session with the current request. It might set response - values (such as one which clears a cookie), or it might not.""" + values (such as one which clears a cookie), or it might not. + + An invalidated session may be used after the call to ``invalidate`` + with the effect that a new session is created to store the data. This + enables workflows requiring an entirely new session, such as in the + case of changing privilege levels or preventing fixation attacks. + """ def changed(): """ Mark the session as changed. A user of a session should diff --git a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl index 76451f9b5..976011ecb 100644 --- a/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl +++ b/pyramid/scaffolds/alchemy/+package+/templates/mytemplate.pt_tmpl @@ -8,12 +8,12 @@ <meta name="author" content="Pylons Project"> <link rel="shortcut icon" href="${request.static_url('{{package}}:static/pyramid-16x16.png')}"> - <title>Starter Template for The Pyramid Web Framework</title> + <title>Alchemy Scaffold for The Pyramid Web Framework</title> <!-- Bootstrap core CSS --> <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> - <!-- Custom styles for this template --> + <!-- Custom styles for this scaffold --> <link href="${request.static_url('{{package}}:static/theme.css')}" rel="stylesheet"> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> @@ -33,16 +33,16 @@ </div> <div class="col-md-10"> <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">starter template</span></h1> - <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework {{pyramid_version}}</span>.</p> </div> </div> </div> <div class="row"> <div class="links"> <ul> - <li class="current-version">Currently v1.5</li> - <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org">Docs</a></li> + <li class="current-version">Generated by v{{pyramid_version}}</li> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/">Docs</a></li> <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> diff --git a/pyramid/scaffolds/alchemy/+package+/views.py_tmpl b/pyramid/scaffolds/alchemy/+package+/views.py_tmpl index be0b45b0d..292bce579 100644 --- a/pyramid/scaffolds/alchemy/+package+/views.py_tmpl +++ b/pyramid/scaffolds/alchemy/+package+/views.py_tmpl @@ -17,12 +17,13 @@ def my_view(request): return Response(conn_err_msg, content_type='text/plain', status_int=500) return {'one': one, 'project': '{{project}}'} + 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_{{project}}_db" script - to initialize your database tables. Check your virtual + 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 diff --git a/pyramid/scaffolds/alchemy/development.ini_tmpl b/pyramid/scaffolds/alchemy/development.ini_tmpl index bdf08171c..e54a8609c 100644 --- a/pyramid/scaffolds/alchemy/development.ini_tmpl +++ b/pyramid/scaffolds/alchemy/development.ini_tmpl @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/environment.html ### [app:main] @@ -32,7 +32,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/logging.html ### [loggers] diff --git a/pyramid/scaffolds/alchemy/production.ini_tmpl b/pyramid/scaffolds/alchemy/production.ini_tmpl index 69b08e458..b316ec9ca 100644 --- a/pyramid/scaffolds/alchemy/production.ini_tmpl +++ b/pyramid/scaffolds/alchemy/production.ini_tmpl @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/environment.html ### [app:main] @@ -23,7 +23,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/logging.html ### [loggers] diff --git a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl index 76451f9b5..3c27906a0 100644 --- a/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl +++ b/pyramid/scaffolds/starter/+package+/templates/mytemplate.pt_tmpl @@ -8,12 +8,12 @@ <meta name="author" content="Pylons Project"> <link rel="shortcut icon" href="${request.static_url('{{package}}:static/pyramid-16x16.png')}"> - <title>Starter Template for The Pyramid Web Framework</title> + <title>Starter Scaffold for The Pyramid Web Framework</title> <!-- Bootstrap core CSS --> <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> - <!-- Custom styles for this template --> + <!-- Custom styles for this scaffold --> <link href="${request.static_url('{{package}}:static/theme.css')}" rel="stylesheet"> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> @@ -33,16 +33,16 @@ </div> <div class="col-md-10"> <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">starter template</span></h1> - <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Starter scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework {{pyramid_version}}</span>.</p> </div> </div> </div> <div class="row"> <div class="links"> <ul> - <li class="current-version">Currently v1.5</li> - <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org">Docs</a></li> + <li class="current-version">Generated by v{{pyramid_version}}</li> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/">Docs</a></li> <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> diff --git a/pyramid/scaffolds/starter/development.ini_tmpl b/pyramid/scaffolds/starter/development.ini_tmpl index 33c454086..842cd61d9 100644 --- a/pyramid/scaffolds/starter/development.ini_tmpl +++ b/pyramid/scaffolds/starter/development.ini_tmpl @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/environment.html ### [app:main] @@ -11,7 +11,7 @@ pyramid.debug_authorization = false pyramid.debug_notfound = false pyramid.debug_routematch = false pyramid.default_locale_name = en -pyramid.includes = +pyramid.includes = pyramid_debugtoolbar # By default, the toolbar only appears for clients from IP addresses @@ -29,7 +29,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/logging.html ### [loggers] diff --git a/pyramid/scaffolds/starter/production.ini_tmpl b/pyramid/scaffolds/starter/production.ini_tmpl index dd2637e5b..6a123abf5 100644 --- a/pyramid/scaffolds/starter/production.ini_tmpl +++ b/pyramid/scaffolds/starter/production.ini_tmpl @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/environment.html ### [app:main] @@ -23,7 +23,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/logging.html ### [loggers] diff --git a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl index 76451f9b5..56efda8b4 100644 --- a/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl +++ b/pyramid/scaffolds/zodb/+package+/templates/mytemplate.pt_tmpl @@ -8,12 +8,12 @@ <meta name="author" content="Pylons Project"> <link rel="shortcut icon" href="${request.static_url('{{package}}:static/pyramid-16x16.png')}"> - <title>Starter Template for The Pyramid Web Framework</title> + <title>ZODB Scaffold for The Pyramid Web Framework</title> <!-- Bootstrap core CSS --> <link href="//oss.maxcdn.com/libs/twitter-bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet"> - <!-- Custom styles for this template --> + <!-- Custom styles for this scaffold --> <link href="${request.static_url('{{package}}:static/theme.css')}" rel="stylesheet"> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> @@ -33,16 +33,16 @@ </div> <div class="col-md-10"> <div class="content"> - <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">starter template</span></h1> - <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework</span>.</p> + <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">ZODB scaffold</span></h1> + <p class="lead">Welcome to <span class="font-normal">${project}</span>, an application generated by<br>the <span class="font-normal">Pyramid Web Framework {{pyramid_version}}</span>.</p> </div> </div> </div> <div class="row"> <div class="links"> <ul> - <li class="current-version">Currently v1.5</li> - <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org">Docs</a></li> + <li class="current-version">Generated by v{{pyramid_version}}</li> + <li><i class="glyphicon glyphicon-bookmark icon-muted"></i><a href="http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/">Docs</a></li> <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li> <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="irc://irc.freenode.net#pyramid">IRC Channel</a></li> <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="http://pylonsproject.org">Pylons Project</a></li> diff --git a/pyramid/scaffolds/zodb/development.ini_tmpl b/pyramid/scaffolds/zodb/development.ini_tmpl index 746f7ded3..f57d559bf 100644 --- a/pyramid/scaffolds/zodb/development.ini_tmpl +++ b/pyramid/scaffolds/zodb/development.ini_tmpl @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/environment.html ### [app:main] @@ -34,7 +34,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/logging.html ### [loggers] diff --git a/pyramid/scaffolds/zodb/production.ini_tmpl b/pyramid/scaffolds/zodb/production.ini_tmpl index 9ce639ec3..c231e159d 100644 --- a/pyramid/scaffolds/zodb/production.ini_tmpl +++ b/pyramid/scaffolds/zodb/production.ini_tmpl @@ -1,6 +1,6 @@ ### # app configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/environment.html ### [app:main] @@ -29,7 +29,7 @@ port = 6543 ### # logging configuration -# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html +# http://docs.pylonsproject.org/projects/pyramid/en/{{pyramid_docs_branch}}/narr/logging.html ### [loggers] diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py index 9a3b53b33..4c1f432fb 100644 --- a/pyramid/scripts/pcreate.py +++ b/pyramid/scripts/pcreate.py @@ -53,6 +53,8 @@ class PCreateCommand(object): action='store_true', help='When a file would be overwritten, interrogate') + pyramid_dist = pkg_resources.get_distribution("pyramid") + def __init__(self, argv, quiet=False): self.quiet = quiet self.options, self.args = self.parser.parse_args(argv[1:]) @@ -82,10 +84,30 @@ class PCreateCommand(object): pkg_name = _bad_chars_re.sub('', project_name.lower()) safe_name = pkg_resources.safe_name(project_name) egg_name = pkg_resources.to_filename(safe_name) + + # get pyramid package version + pyramid_version = self.pyramid_dist.version + + ## map pyramid package version of the documentation branch ## + # if version ends with 'dev' then docs version is 'master' + if self.pyramid_dist.version[-3:] == 'dev': + pyramid_docs_branch = 'master' + else: + # if not version is not 'dev' find the version.major_version string + # and combine it with '-branch' + version_match = re.match(r'(\d+\.\d+)', self.pyramid_dist.version) + if version_match is not None: + pyramid_docs_branch = "%s-branch" % version_match.group() + # if can not parse the version then default to 'latest' + else: + pyramid_docs_branch = 'latest' + vars = { 'project': project_name, 'package': pkg_name, 'egg': egg_name, + 'pyramid_version': pyramid_version, + 'pyramid_docs_branch': pyramid_docs_branch, } for scaffold_name in options.scaffold_name: for scaffold in self.scaffolds: diff --git a/pyramid/static.py b/pyramid/static.py index 63ca58597..aa67568d3 100644 --- a/pyramid/static.py +++ b/pyramid/static.py @@ -58,7 +58,7 @@ class static_view(object): ``cache_max_age`` influences the ``Expires`` and ``Max-Age`` response headers returned by the view (default is 3600 seconds or - five minutes). + one hour). ``use_subpath`` influences whether ``request.subpath`` will be used as ``PATH_INFO`` when calling the underlying WSGI application which actually diff --git a/pyramid/tests/test_scripts/test_pcreate.py b/pyramid/tests/test_scripts/test_pcreate.py index 6516ac229..2488e9595 100644 --- a/pyramid/tests/test_scripts/test_pcreate.py +++ b/pyramid/tests/test_scripts/test_pcreate.py @@ -7,7 +7,7 @@ class TestPCreateCommand(unittest.TestCase): def out(self, msg): self.out_.write(msg) - + def _getTargetClass(self): from pyramid.scripts.pcreate import PCreateCommand return PCreateCommand @@ -25,7 +25,7 @@ class TestPCreateCommand(unittest.TestCase): self.assertEqual(result, 0) out = self.out_.getvalue() self.assertTrue(out.startswith('Available scaffolds')) - + def test_run_show_scaffolds_none_exist(self): cmd = self._makeOne('-l') cmd.scaffolds = [] @@ -33,7 +33,7 @@ class TestPCreateCommand(unittest.TestCase): self.assertEqual(result, 0) out = self.out_.getvalue() self.assertTrue(out.startswith('No scaffolds available')) - + def test_run_no_scaffold_name(self): cmd = self._makeOne() result = cmd.run() @@ -61,6 +61,7 @@ class TestPCreateCommand(unittest.TestCase): cmd = self._makeOne('-s', 'dummy', 'Distro') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( @@ -69,14 +70,17 @@ class TestPCreateCommand(unittest.TestCase): ) self.assertEqual( scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro'}) + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) def test_known_scaffold_absolute_path(self): import os path = os.path.abspath('Distro') cmd = self._makeOne('-s', 'dummy', path) + cmd.pyramid_dist = DummyDist("0.1") scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( @@ -85,7 +89,8 @@ class TestPCreateCommand(unittest.TestCase): ) self.assertEqual( scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro'}) + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) def test_known_scaffold_multiple_rendered(self): import os @@ -93,6 +98,7 @@ class TestPCreateCommand(unittest.TestCase): scaffold1 = DummyScaffold('dummy1') scaffold2 = DummyScaffold('dummy2') cmd.scaffolds = [scaffold1, scaffold2] + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( @@ -101,20 +107,23 @@ class TestPCreateCommand(unittest.TestCase): ) self.assertEqual( scaffold1.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro'}) + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) self.assertEqual( scaffold2.output_dir, os.path.normpath(os.path.join(os.getcwd(), 'Distro')) ) self.assertEqual( scaffold2.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro'}) + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) def test_known_scaffold_with_path_as_project_target_rendered(self): import os cmd = self._makeOne('-s', 'dummy', '/tmp/foo/Distro/') scaffold = DummyScaffold('dummy') cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.1") result = cmd.run() self.assertEqual(result, 0) self.assertEqual( @@ -123,8 +132,73 @@ class TestPCreateCommand(unittest.TestCase): ) self.assertEqual( scaffold.vars, - {'project': 'Distro', 'egg': 'Distro', 'package': 'distro'}) - + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.1', 'pyramid_docs_branch':'0.1-branch'}) + + + def test_scaffold_with_prod_pyramid_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.2") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.2', 'pyramid_docs_branch':'0.2-branch'}) + + def test_scaffold_with_prod_pyramid_long_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.2.1") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.2.1', 'pyramid_docs_branch':'0.2-branch'}) + + def test_scaffold_with_prod_pyramid_unparsable_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("abc") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': 'abc', 'pyramid_docs_branch':'latest'}) + + def test_scaffold_with_dev_pyramid_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.12dev") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.12dev', + 'pyramid_docs_branch': 'master'}) + + def test_scaffold_with_dev_pyramid_long_version(self): + cmd = self._makeOne('-s', 'dummy', 'Distro') + scaffold = DummyScaffold('dummy') + cmd.scaffolds = [scaffold] + cmd.pyramid_dist = DummyDist("0.10.1dev") + result = cmd.run() + self.assertEqual(result, 0) + self.assertEqual( + scaffold.vars, + {'project': 'Distro', 'egg': 'Distro', 'package': 'distro', + 'pyramid_version': '0.10.1dev', + 'pyramid_docs_branch': 'master'}) + + class Test_main(unittest.TestCase): def _callFUT(self, argv): from pyramid.scripts.pcreate import main @@ -142,4 +216,7 @@ class DummyScaffold(object): self.command = command self.output_dir = output_dir self.vars = vars - + +class DummyDist(object): + def __init__(self, version): + self.version = version diff --git a/pyramid/tests/test_wsgi.py b/pyramid/tests/test_wsgi.py index 63499b43b..4ddbc9201 100644 --- a/pyramid/tests/test_wsgi.py +++ b/pyramid/tests/test_wsgi.py @@ -5,6 +5,9 @@ class WSGIAppTests(unittest.TestCase): from pyramid.wsgi import wsgiapp return wsgiapp(app) + def test_wsgiapp_none(self): + self.assertRaises(ValueError, self._callFUT, None) + def test_decorator(self): context = DummyContext() request = DummyRequest() @@ -25,6 +28,9 @@ class WSGIApp2Tests(unittest.TestCase): from pyramid.wsgi import wsgiapp2 return wsgiapp2(app) + def test_wsgiapp2_none(self): + self.assertRaises(ValueError, self._callFUT, None) + def test_decorator_with_subpath_and_view_name(self): context = DummyContext() request = DummyRequest() diff --git a/pyramid/wsgi.py b/pyramid/wsgi.py index d176e4ce5..1c1bded32 100644 --- a/pyramid/wsgi.py +++ b/pyramid/wsgi.py @@ -29,6 +29,10 @@ def wsgiapp(wrapped): view. """ + + if wrapped is None: + raise ValueError('wrapped can not be None') + def decorator(context, request): return request.get_response(wrapped) @@ -69,6 +73,9 @@ def wsgiapp2(wrapped): subpath is used as the ``SCRIPT_NAME``. The new environment is passed to the downstream WSGI application.""" + if wrapped is None: + raise ValueError('wrapped can not be None') + def decorator(context, request): return call_app_with_subpath_as_path_info(request, wrapped) @@ -72,6 +72,7 @@ setup(name='pyramid', description='The Pyramid Web Framework, a Pylons project', long_description=README + '\n\n' + CHANGES, classifiers=[ + "Development Status :: 6 - Mature", "Intended Audience :: Developers", "Programming Language :: Python", "Programming Language :: Python :: 2.6", |
