Permalink
Browse files

move stuff from config.util to registry so it can be a set of API (wh…

…ich are now documented), resolve deferred discriminators in introspectable.register so that a directive can depend on a deferred discriminator, put head-adding code in predicate instead of in add_view itself
  • Loading branch information...
1 parent 695b6de commit d986123332806aadc43b1daab396ff5200ec10ce @mcdonc mcdonc committed Aug 7, 2012
View
@@ -38,3 +38,17 @@
This class is new as of :app:`Pyramid` 1.3.
+.. autoclass:: Deferred
+
+ This class is new as of :app:`Pyramid` 1.4.
+
+.. autofunction:: undefer
+
+ This function is new as of :app:`Pyramid` 1.4.
+
+.. autoclass:: predvalseq
+
+ This class is new as of :app:`Pyramid` 1.4.
+
+
+
@@ -45,6 +45,8 @@
Introspectable,
Introspector,
Registry,
+ Deferred,
+ undefer,
)
from pyramid.router import Router
@@ -72,7 +74,6 @@
from pyramid.config.util import (
action_method,
ActionInfo,
- Deferred,
)
from pyramid.config.views import ViewsConfiguratorMixin
from pyramid.config.zca import ZCAConfiguratorMixin
@@ -1067,11 +1068,6 @@ def execute_actions(self, clear=True, introspector=None):
if clear:
del self.actions[:]
-def undefer(v):
- if isinstance(v, Deferred):
- v = v.resolve()
- return v
-
# this function is licensed under the ZPL (stolen from Zope)
def resolveConflicts(actions):
"""Resolve conflicting actions
@@ -29,7 +29,11 @@ def __call__(self, context, request):
class RequestMethodPredicate(object):
def __init__(self, val, config):
- self.val = as_sorted_tuple(val)
+ request_method = as_sorted_tuple(val)
+ if 'GET' in request_method and 'HEAD' not in request_method:
+ # GET implies HEAD too
+ request_method = as_sorted_tuple(request_method + ('HEAD',))
+ self.val = request_method
def text(self):
return 'request_method = %s' % (','.join(self.val))
View
@@ -10,14 +10,14 @@
)
from pyramid.exceptions import ConfigurationError
+from pyramid.registry import predvalseq
from pyramid.request import route_request_iface
from pyramid.urldispatch import RoutesMapper
from pyramid.config.util import (
action_method,
as_sorted_tuple,
PredicateList,
- predvalseq,
)
from pyramid.config import predicates
View
@@ -11,6 +11,8 @@
from pyramid.exceptions import ConfigurationError
+from pyramid.registry import predvalseq
+
from hashlib import md5
MAX_ORDER = 1 << 30
@@ -294,13 +296,3 @@ def make(self, config, **kw):
order = (MAX_ORDER - score) / (len(preds) + 1)
return order, preds, phash.hexdigest()
-class predvalseq(tuple):
- pass
-
-class Deferred(object):
- def __init__(self, func):
- self.func = func
-
- def resolve(self):
- return self.func()
-
View
@@ -55,6 +55,11 @@
HTTPNotFound,
)
+from pyramid.registry import (
+ predvalseq,
+ Deferred,
+ )
+
from pyramid.security import NO_PERMISSION_REQUIRED
from pyramid.static import static_view
from pyramid.threadlocal import get_current_registry
@@ -64,18 +69,17 @@
AppendSlashNotFoundViewFactory,
)
-from pyramid.util import object_description
+from pyramid.util import (
+ object_description,
+ )
from pyramid.config import predicates
from pyramid.config.util import (
- Deferred,
DEFAULT_PHASH,
MAX_ORDER,
action_method,
- as_sorted_tuple,
PredicateList,
- predvalseq,
)
urljoin = urlparse.urljoin
@@ -1029,12 +1033,6 @@ def view(context, request):
raise ConfigurationError(
'request_type must be an interface, not %s' % request_type)
- if request_method is not None:
- request_method = as_sorted_tuple(request_method)
- if 'GET' in request_method and 'HEAD' not in request_method:
- # GET implies HEAD too
- request_method = as_sorted_tuple(request_method + ('HEAD',))
-
if context is None:
context = for_
View
@@ -191,14 +191,20 @@ def relate(self, category_name, discriminator):
def unrelate(self, category_name, discriminator):
self._relations.append((False, category_name, discriminator))
+ def _assert_resolved(self):
+ assert undefer(self.discriminator) is self.discriminator
+
@property
def discriminator_hash(self):
+ self._assert_resolved()
return hash(self.discriminator)
def __hash__(self):
+ self._assert_resolved()
return hash((self.category_name,) + (self.discriminator,))
def __repr__(self):
+ self._assert_resolved()
return '<%s category %r, discriminator %r>' % (self.__class__.__name__,
self.category_name,
self.discriminator)
@@ -209,9 +215,11 @@ def __nonzero__(self):
__bool__ = __nonzero__ # py3
def register(self, introspector, action_info):
+ self.discriminator = undefer(self.discriminator)
self.action_info = action_info
introspector.add(self)
for relate, category_name, discriminator in self._relations:
+ discriminator = undefer(discriminator)
if relate:
method = introspector.relate
else:
@@ -221,4 +229,29 @@ def register(self, introspector, action_info):
(category_name, discriminator)
)
+class Deferred(object):
+ """ Can be used by a third-party configuration extender to wrap a
+ :term:`discriminator` during configuration if an immediately hashable
+ discriminator cannot be computed because it relies on unresolved values.
+ The function should accept no arguments and should return a hashable
+ discriminator."""
+ def __init__(self, func):
+ self.func = func
+
+ def resolve(self):
+ return self.func()
+
+def undefer(v):
+ """ Function which accepts an object and returns it unless it is a
+ :class:`pyramid.registry.Deferred` instance. If it is an instance of
+ that class, its ``resolve`` method is called, and the result of the
+ method is returned."""
+ if isinstance(v, Deferred):
+ v = v.resolve()
+ return v
+
+class predvalseq(tuple):
+ """ A subtype of tuple used to represent a sequence of predicate values """
+ pass
+
global_registry = Registry('global')
@@ -33,6 +33,10 @@ class TestRequestMethodPredicate(unittest.TestCase):
def _makeOne(self, val):
from pyramid.config.predicates import RequestMethodPredicate
return RequestMethodPredicate(val, None)
+
+ def test_ctor_get_but_no_head(self):
+ inst = self._makeOne('GET')
+ self.assertEqual(inst.val, ('GET', 'HEAD'))
def test___call___true_single(self):
inst = self._makeOne('GET')
View
@@ -280,3 +280,4 @@ def shortrepr(object, closer):
if len(r) > 100:
r = r[:100] + ' ... %s' % closer
return r
+

0 comments on commit d986123

Please sign in to comment.