summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt27
-rw-r--r--CONTRIBUTORS.txt2
-rw-r--r--docs/conf.py3
-rw-r--r--docs/narr/install.rst23
-rw-r--r--docs/narr/project.rst32
-rw-r--r--docs/narr/renderers.rst10
-rw-r--r--docs/narr/sessions.rst15
-rw-r--r--docs/quick_tour.rst16
-rw-r--r--docs/quick_tour/jinja2/hello_world.jinja23
-rw-r--r--docs/quick_tutorial/requirements.rst24
-rw-r--r--pyramid/authorization.py3
-rw-r--r--pyramid/encode.py6
-rw-r--r--pyramid/scaffolds/alchemy/+package+/static/pyramid-small.pngbin7044 -> 0 bytes
-rw-r--r--pyramid/scaffolds/starter/+package+/static/pyramid-small.pngbin7044 -> 0 bytes
-rw-r--r--pyramid/scaffolds/zodb/+package+/static/pyramid-small.pngbin7044 -> 0 bytes
-rw-r--r--pyramid/scripts/pcreate.py2
-rw-r--r--pyramid/tests/test_authorization.py13
-rw-r--r--pyramid/tests/test_encode.py12
-rw-r--r--pyramid/tests/test_scripts/test_pcreate.py15
19 files changed, 144 insertions, 62 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 8b2210a99..67cefb79a 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,11 +1,38 @@
Unreleased
==========
+Bug Fixes
+---------
+
+- Fix the ``pcreate`` script so that when the target directory name ends with a
+ slash it does not produce a non-working project directory structure.
+ Previously saying ``pcreate -s starter /foo/bar/`` produced different output
+ than saying ``pcreate -s starter /foo/bar``. The former did not work
+ properly.
+
+- Fix the ``principals_allowed_by_permission`` method of
+ ``ACLAuthorizationPolicy`` so it anticipates a callable ``__acl__``
+ on resources. Previously it did not try to call the ``__acl__``
+ if it was callable.
+
Documentation
-------------
- Added a "Quick Tutorial" to go with the Quick Tour
+- Removed mention of ``pyramid_beaker`` from docs. Beaker is no longer
+ maintained. Point people at ``pyramid_redis_sessions`` instead.
+
+Backwards Incompatibilities
+---------------------------
+
+- The key/values in the ``_query`` parameter of ``request.route_url`` and the
+ ``query`` parameter of ``request.resource_url`` (and their variants), used
+ to encode a value of ``None`` as the string ``'None'``, leaving the resulting
+ query string to be ``a=b&key=None``. The value is now dropped in this
+ situation, leaving a query string of ``a=b&key``.
+ See https://github.com/Pylons/pyramid/issues/1119
+
1.5a2 (2013-09-22)
==================
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index 1a5b975d7..bfe22e540 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -222,3 +222,5 @@ Contributors
- Takahiro Fujiwara, 2013/08/28
- Doug Hellmann, 2013/09/06
+
+- Karl O. Pinc, 2013/09/27
diff --git a/docs/conf.py b/docs/conf.py
index ee852aa51..3b6e75a17 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -73,9 +73,6 @@ intersphinx_mapping = {
'http://docs.pylonsproject.org/projects/deform/en/latest',
None),
'sqla': ('http://docs.sqlalchemy.org/en/latest', None),
- 'beaker': (
- 'http://docs.pylonsproject.org/projects/pyramid_beaker/en/latest',
- None),
'who': ('http://docs.repoze.org/who/latest', None),
'python': ('http://docs.python.org', None),
'python3': ('http://docs.python.org/3', None),
diff --git a/docs/narr/install.rst b/docs/narr/install.rst
index fb67b899b..e419a8b20 100644
--- a/docs/narr/install.rst
+++ b/docs/narr/install.rst
@@ -25,6 +25,10 @@ on :term:`PyPy` (1.9+).
:app:`Pyramid` installation does not require the compilation of any C code, so
you need only a Python interpreter that meets the requirements mentioned.
+Some :app:`Pyramid` dependencies may attempt to build C extensions for
+performance speedups. If a compiler or Python headers are unavailable the
+dependency will fall back to using pure Python instead.
+
For Mac OS X Users
~~~~~~~~~~~~~~~~~~
@@ -285,13 +289,20 @@ Installing :app:`Pyramid` Into the Virtual Python Environment
After you've got your virtualenv installed, you may install :app:`Pyramid`
itself using the following commands:
-.. code-block:: text
-
- $ $VENV/bin/easy_install pyramid
+.. parsed-literal::
+
+ $ $VENV/bin/easy_install "pyramid==\ |release|\ "
The ``easy_install`` command will take longer than the previous ones to
complete, as it downloads and installs a number of dependencies.
+.. note::
+
+ If you see any warnings and/or errors related to failing to compile the C
+ extensions, in most cases you may safely ignore those errors. If you wish
+ to use the C extensions, please verify that you have a functioning compiler
+ and the Python header files installed.
+
.. index::
single: installing on Windows
@@ -357,9 +368,9 @@ You can use Pyramid on Windows under Python 2 or 3.
#. Use ``easy_install`` to get :app:`Pyramid` and its direct dependencies
installed:
- .. code-block:: text
-
- c:\env> %VENV%\Scripts\easy_install pyramid
+ .. parsed-literal::
+
+ c:\\env> %VENV%\\Scripts\\easy_install "pyramid==\ |release|\ "
What Gets Installed
-------------------
diff --git a/docs/narr/project.rst b/docs/narr/project.rst
index 602f15fef..2acc81e17 100644
--- a/docs/narr/project.rst
+++ b/docs/narr/project.rst
@@ -144,7 +144,7 @@ contains no space characters, so it's wise to *avoid* a path that contains
i.e. ``My Documents``. As a result, the author, when he uses Windows, just
puts his projects in ``C:\projects``.
-.. warning::
+.. warning::
You’ll need to avoid using ``pcreate`` to create a project with the same
name as a Python standard library component. In particular, this means you
@@ -871,18 +871,19 @@ specification` that specifies the ``mytemplate.pt`` file within the
``templates`` directory of the ``myproject`` package. The asset
specification could have also been specified as
``myproject:templates/mytemplate.pt``; the leading package name and colon is
-optional. The template file it actually points to is a :term:`Chameleon` ZPT
-template file.
+optional. The template file pointed to is a :term:`Chameleon` ZPT
+template file (``templates/my_template.pt``).
This view callable function is handed a single piece of information: the
:term:`request`. The *request* is an instance of the :term:`WebOb`
``Request`` class representing the browser's request to our server.
-This view returns a dictionary. When this view is invoked, a
-:term:`renderer` converts the dictionary returned by the view into HTML, and
-returns the result as the :term:`response`. This view is configured to
-invoke a renderer which uses a :term:`Chameleon` ZPT template
-(``templates/my_template.pt``).
+.. note:: Dictionaries provide values to :term:`template`s.
+
+This view is configured to invoke a :term:`renderer` on a template. The
+dictionary the view returns (on line 6) provides the value the renderer
+substitutes into the template when generating HTML. The renderer then
+returns the HTML in a :term:`response`.
See :ref:`views_which_use_a_renderer` for more information about how views,
renderers, and templates relate and cooperate.
@@ -971,12 +972,15 @@ named ``views`` instead of within a single ``views.py`` file, you might:
- Create a ``views`` directory inside your ``myproject`` package directory
(the same directory which holds ``views.py``).
-- *Move* the existing ``views.py`` file to a file inside the new ``views``
- directory named, say, ``blog.py``.
+- Create a file within the new ``views`` directory named ``__init__.py``. (It
+ can be empty. This just tells Python that the ``views`` directory is a
+ *package*.)
-- Create a file within the new ``views`` directory named ``__init__.py`` (it
- can be empty, this just tells Python that the ``views`` directory is a
- *package*.
+- *Move* the existing ``views.py`` file to a file inside the new ``views``
+ directory named, say, ``blog.py``. Because the ``templates`` directory
+ remains in the ``myproject`` package, the template :term:`asset
+ specification`s in ``blog.py`` must now be fully qualified with the
+ project's package name (``myproject:templates/blog.pt``).
You can then continue to add view callable functions to the ``blog.py``
module, but you can also add other ``.py`` files which contain view callable
@@ -1025,7 +1029,7 @@ server. Waitress is a server that is suited for development and light
production usage. It's not the fastest nor the most featureful WSGI server.
Instead, its main feature is that it works on all platforms that Pyramid
needs to run on, making it a good choice as a default server from the
-perspective of Pyramid's developers.
+perspective of Pyramid's developers.
Any WSGI server is capable of running a :app:`Pyramid` application. But we
suggest you stick with the default server for development, and that you wait
diff --git a/docs/narr/renderers.rst b/docs/narr/renderers.rst
index 3059aef35..4046c67fa 100644
--- a/docs/narr/renderers.rst
+++ b/docs/narr/renderers.rst
@@ -49,10 +49,12 @@ Writing View Callables Which Use a Renderer
-------------------------------------------
As we've seen, a view callable needn't always return a Response object.
-Instead, it may return an arbitrary Python object, with the expectation
-that a :term:`renderer` will convert that object into a response instance on
-your behalf. Some renderers use a templating system; other renderers use
-object serialization techniques.
+Instead, it may return an arbitrary Python object, with the expectation that
+a :term:`renderer` will convert that object into a response instance on your
+behalf. Some renderers use a templating system; other renderers use object
+serialization techniques. In practice, renderers obtain application data
+values from Python dictionaries so, in practice, view callables which use
+renderers return Python dictionaries.
View configuration can vary the renderer associated with a view callable via
the ``renderer`` attribute. For example, this call to
diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst
index db1e0ea20..f4da5d82a 100644
--- a/docs/narr/sessions.rst
+++ b/docs/narr/sessions.rst
@@ -151,8 +151,6 @@ Some gotchas:
you've changed sessioning data.
.. index::
- single: pyramid_beaker
- single: Beaker
single: pyramid_redis_sessions
single: session factory (alternates)
@@ -161,20 +159,11 @@ Some gotchas:
Using Alternate Session Factories
---------------------------------
-At the time of this writing, exactly two alternate session factories
-exist.
-
-The first is named ``pyramid_redis_sessions``. It can be downloaded from PyPI.
+At the time of this writing, exactly one project-endorsed alternate session
+factory exists named``pyramid_redis_sessions``. It can be downloaded from PyPI.
It uses Redis as a backend. It is the recommended persistent session solution
at the time of this writing.
-The second is named ``pyramid_beaker``. This is a session factory that uses the
-`Beaker <http://beaker.groovie.org/>`_ library as a backend. Beaker has
-support for file-based sessions, database based sessions, and encrypted
-cookie-based sessions. See `the pyramid_beaker documentation
-<http://docs.pylonsproject.org/projects/pyramid_beaker/en/latest/>`_ for more
-information about ``pyramid_beaker``.
-
.. index::
single: session factory (custom)
diff --git a/docs/quick_tour.rst b/docs/quick_tour.rst
index 434dbdad5..98584e608 100644
--- a/docs/quick_tour.rst
+++ b/docs/quick_tour.rst
@@ -17,26 +17,26 @@ Pyramid is a breeze. Unfortunately "standard" is not so simple in Python.
For this Quick Tour, it means:
`Python <http://www.python.org/download/releases/>`_, a
`virtual environment <http://docs.python.org/dev/library/venv.html>`_
-(or `virtualenv for Python 2.7 <https://pypi.python.org/pypi/virtualenv>`_,
+(or `virtualenv for Python 2.7 <https://pypi.python.org/pypi/virtualenv>`_),
and `setuptools <https://pypi.python.org/pypi/setuptools/>`_.
As an example, for Python 3.3+ on Linux:
-.. code-block:: bash
+.. parsed-literal::
$ pyvenv env33
$ wget https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py -O - | env33/bin/python
- $ env33/bin/easy_install pyramid
+ $ env33/bin/easy_install "pyramid==\ |release|\ "
For Windows:
-.. code-block:: posh
+.. parsed-literal::
# Use your browser to download:
# https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py
- c:\> c:\Python33\python -m venv env33
- c:\> env33\Scripts\python ez_setup.py
- c:\> env33\Scripts\easy_install pyramid
+ c:\\> c:\\Python33\\python -m venv env33
+ c:\\> env33\\Scripts\\python ez_setup.py
+ c:\\> env33\\Scripts\\easy_install "pyramid==\ |release|\ "
Of course Pyramid runs fine on Python 2.6+, as do the examples in this
*Quick Tour*. We're just showing Python 3 a little love (Pyramid had
@@ -297,7 +297,7 @@ The only change in our view...point the renderer at the ``.jinja2`` file:
Our Jinja2 template is very similar to our previous template:
.. literalinclude:: quick_tour/jinja2/hello_world.jinja2
- :language: jinja
+ :language: html
Pyramid's templating add-ons register a new kind of renderer into your
application. The renderer registration maps to different kinds of
diff --git a/docs/quick_tour/jinja2/hello_world.jinja2 b/docs/quick_tour/jinja2/hello_world.jinja2
index e177744b5..7a902dd3a 100644
--- a/docs/quick_tour/jinja2/hello_world.jinja2
+++ b/docs/quick_tour/jinja2/hello_world.jinja2
@@ -1,4 +1,5 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
+<!DOCTYPE html>
+<html lang="en">
<head>
<title>Hello World</title>
</head>
diff --git a/docs/quick_tutorial/requirements.rst b/docs/quick_tutorial/requirements.rst
index df63ff912..40e818807 100644
--- a/docs/quick_tutorial/requirements.rst
+++ b/docs/quick_tutorial/requirements.rst
@@ -94,23 +94,23 @@ and where our virtual environment will reside:
Final directory structure.
-The commands to do so are as follows:
+For Linux, the commands to do so are as follows:
.. code-block:: bash
# Mac and Linux
$ cd ~
- $ mkdir projects
- $ cd projects
- $ mkdir quick_tutorial
- $ cd quick_tutorial
+ $ mkdir -p projects/quick_tutorial
+ $ cd projects/quick_tutorial
+
+For Windows:
+
+.. code-block:: posh
# Windows
c:\> cd \
- c:\> mkdir projects
- c:\> cd projects
- c:\> mkdir quick_tutorial
- c:\> cd quick_tutorial
+ c:\> mkdir projects\quick_tutorial
+ c:\> cd projects\quick_tutorial
In the above figure, your user home directory is represented by ``~``. In
your home directory, all of your projects are in the ``projects`` directory.
@@ -208,13 +208,13 @@ Install Pyramid
We have our Python standard prerequisites out of the way. The Pyramid
part is pretty easy:
-.. code-block:: bash
+.. parsed-literal::
# Mac and Linux
- $ $VENV/bin/easy_install pyramid
+ $ $VENV/bin/easy_install "pyramid==\ |release|\ "
# Windows
- c:\> %VENV%\Scripts\easy_install pyramid
+ c:\\> %VENV%\\Scripts\\easy_install "pyramid==\ |release|\ "
Our Python virtual environment now has the Pyramid software available.
diff --git a/pyramid/authorization.py b/pyramid/authorization.py
index 1fd05e244..5e7baa19d 100644
--- a/pyramid/authorization.py
+++ b/pyramid/authorization.py
@@ -122,6 +122,9 @@ class ACLAuthorizationPolicy(object):
allowed_here = set()
denied_here = set()
+ if acl and callable(acl):
+ acl = acl()
+
for ace_action, ace_principal, ace_permissions in acl:
if not is_nonstr_iter(ace_permissions):
ace_permissions = [ace_permissions]
diff --git a/pyramid/encode.py b/pyramid/encode.py
index 65bc95032..9e190bc21 100644
--- a/pyramid/encode.py
+++ b/pyramid/encode.py
@@ -32,6 +32,10 @@ def urlencode(query, doseq=True):
See the Python stdlib documentation for ``urllib.urlencode`` for
more information.
+
+ .. versionchanged:: 1.5
+ In a key/value pair, if the value is ``None`` then it will be
+ dropped from the resulting output.
"""
try:
# presumed to be a dictionary
@@ -50,6 +54,8 @@ def urlencode(query, doseq=True):
x = _enc(x)
result += '%s%s=%s' % (prefix, k, x)
prefix = '&'
+ elif v is None:
+ result += '%s%s=' % (prefix, k)
else:
v = _enc(v)
result += '%s%s=%s' % (prefix, k, v)
diff --git a/pyramid/scaffolds/alchemy/+package+/static/pyramid-small.png b/pyramid/scaffolds/alchemy/+package+/static/pyramid-small.png
deleted file mode 100644
index a5bc0ade7..000000000
--- a/pyramid/scaffolds/alchemy/+package+/static/pyramid-small.png
+++ /dev/null
Binary files differ
diff --git a/pyramid/scaffolds/starter/+package+/static/pyramid-small.png b/pyramid/scaffolds/starter/+package+/static/pyramid-small.png
deleted file mode 100644
index a5bc0ade7..000000000
--- a/pyramid/scaffolds/starter/+package+/static/pyramid-small.png
+++ /dev/null
Binary files differ
diff --git a/pyramid/scaffolds/zodb/+package+/static/pyramid-small.png b/pyramid/scaffolds/zodb/+package+/static/pyramid-small.png
deleted file mode 100644
index a5bc0ade7..000000000
--- a/pyramid/scaffolds/zodb/+package+/static/pyramid-small.png
+++ /dev/null
Binary files differ
diff --git a/pyramid/scripts/pcreate.py b/pyramid/scripts/pcreate.py
index ba4eb0856..5e2240856 100644
--- a/pyramid/scripts/pcreate.py
+++ b/pyramid/scripts/pcreate.py
@@ -77,8 +77,8 @@ class PCreateCommand(object):
def render_scaffolds(self):
options = self.options
args = self.args
- project_name = os.path.basename(args[0])
output_dir = os.path.abspath(os.path.normpath(args[0]))
+ project_name = os.path.basename(os.path.split(output_dir)[1])
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)
diff --git a/pyramid/tests/test_authorization.py b/pyramid/tests/test_authorization.py
index 60b1b0c8d..05cd3b4f8 100644
--- a/pyramid/tests/test_authorization.py
+++ b/pyramid/tests/test_authorization.py
@@ -146,6 +146,19 @@ class TestACLAuthorizationPolicy(unittest.TestCase):
policy.principals_allowed_by_permission(context, 'read'))
self.assertEqual(result, ['chrism'])
+ def test_principals_allowed_by_permission_callable_acl(self):
+ from pyramid.security import Allow
+ from pyramid.security import DENY_ALL
+ context = DummyContext()
+ acl = lambda: [ (Allow, 'chrism', ('read', 'write')),
+ DENY_ALL,
+ (Allow, 'other', 'read') ]
+ context.__acl__ = acl
+ policy = self._makeOne()
+ result = sorted(
+ policy.principals_allowed_by_permission(context, 'read'))
+ self.assertEqual(result, ['chrism'])
+
def test_principals_allowed_by_permission_string_permission(self):
from pyramid.security import Allow
context = DummyContext()
diff --git a/pyramid/tests/test_encode.py b/pyramid/tests/test_encode.py
index 736ecb5b3..908249877 100644
--- a/pyramid/tests/test_encode.py
+++ b/pyramid/tests/test_encode.py
@@ -41,6 +41,18 @@ class UrlEncodeTests(unittest.TestCase):
result = self._callFUT({'a':1})
self.assertEqual(result, 'a=1')
+ def test_None_value(self):
+ result = self._callFUT([('a', None)])
+ self.assertEqual(result, 'a=')
+
+ def test_None_value_with_prefix(self):
+ result = self._callFUT([('a', '1'), ('b', None)])
+ self.assertEqual(result, 'a=1&b=')
+
+ def test_None_value_with_prefix_values(self):
+ result = self._callFUT([('a', '1'), ('b', None), ('c', None)])
+ self.assertEqual(result, 'a=1&b=&c=')
+
class URLQuoteTests(unittest.TestCase):
def _callFUT(self, val, safe=''):
from pyramid.encode import url_quote
diff --git a/pyramid/tests/test_scripts/test_pcreate.py b/pyramid/tests/test_scripts/test_pcreate.py
index 1406d3911..6516ac229 100644
--- a/pyramid/tests/test_scripts/test_pcreate.py
+++ b/pyramid/tests/test_scripts/test_pcreate.py
@@ -110,6 +110,21 @@ class TestPCreateCommand(unittest.TestCase):
scaffold2.vars,
{'project': 'Distro', 'egg': 'Distro', 'package': 'distro'})
+ 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]
+ result = cmd.run()
+ self.assertEqual(result, 0)
+ self.assertEqual(
+ scaffold.output_dir,
+ os.path.normpath(os.path.join(os.getcwd(), '/tmp/foo/Distro'))
+ )
+ self.assertEqual(
+ scaffold.vars,
+ {'project': 'Distro', 'egg': 'Distro', 'package': 'distro'})
+
class Test_main(unittest.TestCase):
def _callFUT(self, argv):
from pyramid.scripts.pcreate import main