summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2012-08-16 10:26:32 -0400
committerChris McDonough <chrism@plope.com>2012-08-16 10:26:32 -0400
commit8c7b0f14b2c55e653bb0d4a18e3de299b7abe208 (patch)
tree22635d4768befaac2b111af5da8ff248e8ef837b
parent1431f5a99812ac03c74767fe648cbe338bc86133 (diff)
parent7401b8eeded5d2d0167edabbc9f720f8ae235359 (diff)
downloadpyramid-8c7b0f14b2c55e653bb0d4a18e3de299b7abe208.tar.gz
pyramid-8c7b0f14b2c55e653bb0d4a18e3de299b7abe208.tar.bz2
pyramid-8c7b0f14b2c55e653bb0d4a18e3de299b7abe208.zip
Merge branch 'master' of github.com:Pylons/pyramid
-rw-r--r--CHANGES.txt15
-rw-r--r--docs/api/config.rst1
-rw-r--r--pyramid/config/__init__.py17
-rw-r--r--pyramid/config/security.py20
-rw-r--r--pyramid/tests/test_config/test_security.py9
5 files changed, 51 insertions, 11 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index e092b1545..f02925585 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -85,3 +85,18 @@ Features
- When there is a predicate mismatch exception (seen when no view matches for
a given request due to predicates not working), the exception now contains
a textual description of the predicate which didn't match.
+
+- An ``add_permission`` directive method was added to the Configurator. This
+ directive registers a free-standing permission introspectable into the
+ Pyramid introspection system. Frameworks built atop Pyramid can thus use
+ the the ``permissions`` introspectable category data to build a
+ comprehensive list of permissions supported by a running system. Before
+ this method was added, permissions were already registered in this
+ introspectable category as a side effect of naming them in an ``add_view``
+ call, this method just makes it possible to arrange for a permission to be
+ put into the ``permissions`` introspectable category without naming it
+ along with an associated view. Here's an example of usage of
+ ``add_permission``::
+
+ config = Configurator()
+ config.add_permission('view')
diff --git a/docs/api/config.rst b/docs/api/config.rst
index bc9e067b1..1b887988a 100644
--- a/docs/api/config.rst
+++ b/docs/api/config.rst
@@ -36,6 +36,7 @@
.. automethod:: set_authentication_policy
.. automethod:: set_authorization_policy
.. automethod:: set_default_permission
+ .. automethod:: add_permission
:methodcategory:`Setting Request Properties`
diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py
index a45dca255..6010740ca 100644
--- a/pyramid/config/__init__.py
+++ b/pyramid/config/__init__.py
@@ -4,7 +4,6 @@ import logging
import operator
import os
import sys
-import types
import warnings
import venusian
@@ -23,7 +22,6 @@ from pyramid.compat import (
text_,
reraise,
string_types,
- PY3,
)
from pyramid.events import ApplicationCreated
@@ -45,7 +43,6 @@ from pyramid.registry import (
Introspectable,
Introspector,
Registry,
- Deferred,
undefer,
)
@@ -553,10 +550,9 @@ class Configurator(
introspectables = ()
if autocommit:
- if isinstance(discriminator, Deferred):
- # callables can depend on the side effects of resolving a
- # deferred discriminator
- discriminator.resolve()
+ # callables can depend on the side effects of resolving a
+ # deferred discriminator
+ undefer(discriminator)
if callable is not None:
callable(*args, **kw)
for introspectable in introspectables:
@@ -786,10 +782,9 @@ class Configurator(
c, action_wrap = c
if action_wrap:
c = action_method(c)
- if PY3: # pragma: no cover
- m = types.MethodType(c, self)
- else:
- m = types.MethodType(c, self, self.__class__)
+ # Create a bound method (works on both Py2 and Py3)
+ # http://stackoverflow.com/a/1015405/209039
+ m = c.__get__(self, self.__class__)
return m
def with_package(self, package):
diff --git a/pyramid/config/security.py b/pyramid/config/security.py
index e8ef1518d..567999cc4 100644
--- a/pyramid/config/security.py
+++ b/pyramid/config/security.py
@@ -137,3 +137,23 @@ class SecurityConfiguratorMixin(object):
introspectables=(intr, perm_intr,))
+ def add_permission(self, permission_name):
+ """
+ A configurator directive which registers a free-standing
+ permission without associating it with a view callable. This can be
+ used so that the permission shows up in the introspectable data under
+ the ``permissions`` category (permissions mentioned via ``add_view``
+ already end up in there). For example::
+
+ config = Configurator()
+ config.add_permission('view')
+ """
+ intr = self.introspectable(
+ 'permissions',
+ permission_name,
+ permission_name,
+ 'permission'
+ )
+ intr['value'] = permission_name
+ self.action(None, introspectables=(intr,))
+
diff --git a/pyramid/tests/test_config/test_security.py b/pyramid/tests/test_config/test_security.py
index d05d1d471..817f6ce02 100644
--- a/pyramid/tests/test_config/test_security.py
+++ b/pyramid/tests/test_config/test_security.py
@@ -89,3 +89,12 @@ class ConfiguratorSecurityMethodsTests(unittest.TestCase):
self.assertEqual(config.registry.getUtility(IDefaultPermission),
'view')
+ def test_add_permission(self):
+ config = self._makeOne(autocommit=True)
+ config.add_permission('perm')
+ cat = config.registry.introspector.get_category('permissions')
+ self.assertEqual(len(cat), 1)
+ D = cat[0]
+ intr = D['introspectable']
+ self.assertEqual(intr['value'], 'perm')
+