From 6b180cbb77d6c5bee0e75220d93fc1800d1217df Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 15 Aug 2012 22:49:59 -0400 Subject: - 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') --- CHANGES.txt | 15 +++++++++++++++ docs/api/config.rst | 1 + pyramid/config/security.py | 20 ++++++++++++++++++++ pyramid/tests/test_config/test_security.py | 9 +++++++++ 4 files changed, 45 insertions(+) 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/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') + -- cgit v1.2.3 From c7cc885483dadeb44b5e9b900e01d61ca743a664 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 16 Aug 2012 02:50:30 -0400 Subject: - Use nicer spelling for generating a bound method (thanks to Raydeo and http://stackoverflow.com/a/1015405/209039) --- pyramid/config/__init__.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index a45dca255..547fa9e4a 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 @@ -786,10 +784,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): -- cgit v1.2.3 From 7401b8eeded5d2d0167edabbc9f720f8ae235359 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 16 Aug 2012 02:57:19 -0400 Subject: use undefer instead of pulling the oxcart by hand --- pyramid/config/__init__.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pyramid/config/__init__.py b/pyramid/config/__init__.py index 547fa9e4a..6010740ca 100644 --- a/pyramid/config/__init__.py +++ b/pyramid/config/__init__.py @@ -43,7 +43,6 @@ from pyramid.registry import ( Introspectable, Introspector, Registry, - Deferred, undefer, ) @@ -551,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: -- cgit v1.2.3