diff options
| author | Michael Merickel <michael@merickel.org> | 2019-09-20 00:09:29 -0500 |
|---|---|---|
| committer | Michael Merickel <michael@merickel.org> | 2019-10-02 10:03:07 -0500 |
| commit | ba311842b667348c51fb1a479ae08a042434f1bc (patch) | |
| tree | a34f4945305113a8666618e255281858ee2f825a | |
| parent | be62391821676393b7ad5ab51655892e991c2ae0 (diff) | |
| download | pyramid-ba311842b667348c51fb1a479ae08a042434f1bc.tar.gz pyramid-ba311842b667348c51fb1a479ae08a042434f1bc.tar.bz2 pyramid-ba311842b667348c51fb1a479ae08a042434f1bc.zip | |
define an IPredicateInfo instead of passing the full configurator to predicates
| -rw-r--r-- | docs/api/interfaces.rst | 21 | ||||
| -rw-r--r-- | src/pyramid/config/predicates.py | 16 | ||||
| -rw-r--r-- | src/pyramid/interfaces.py | 85 | ||||
| -rw-r--r-- | tests/test_config/test_predicates.py | 6 |
4 files changed, 127 insertions, 1 deletions
diff --git a/docs/api/interfaces.rst b/docs/api/interfaces.rst index e542a6be0..08c67c385 100644 --- a/docs/api/interfaces.rst +++ b/docs/api/interfaces.rst @@ -109,3 +109,24 @@ Other Interfaces .. autointerface:: IViewDeriverInfo :members: + + .. autointerface:: IPredicateFactory + :members: + + .. autointerface:: IPredicateInfo + :members: + + .. autointerface:: IPredicate + :members: + + .. autointerface:: IRoutePredicate + :inherited-members: + :members: + + .. autointerface:: ISubscriberPredicate + :inherited-members: + :members: + + .. autointerface:: IViewPredicate + :inherited-members: + :members: diff --git a/src/pyramid/config/predicates.py b/src/pyramid/config/predicates.py index 3eb07c17d..ffdff5c21 100644 --- a/src/pyramid/config/predicates.py +++ b/src/pyramid/config/predicates.py @@ -98,6 +98,14 @@ class not_(object): # over = before +class PredicateInfo(object): + def __init__(self, package, registry, settings, maybe_dotted): + self.package = package + self.registry = registry + self.settings = settings + self.maybe_dotted = maybe_dotted + + class PredicateList(object): def __init__(self): self.sorter = TopologicalSorter() @@ -134,6 +142,12 @@ class PredicateList(object): phash = md5() weights = [] preds = [] + info = PredicateInfo( + package=config.package, + registry=config.registry, + settings=config.get_settings(), + maybe_dotted=config.maybe_dotted, + ) for n, (name, predicate_factory) in enumerate(ordered): vals = kw.pop(name, None) if vals is None: # XXX should this be a sentinel other than None? @@ -146,7 +160,7 @@ class PredicateList(object): if isinstance(val, not_): realval = val.value notted = True - pred = predicate_factory(realval, config) + pred = predicate_factory(realval, info) if notted: pred = Notted(pred) hashes = pred.phash() diff --git a/src/pyramid/interfaces.py b/src/pyramid/interfaces.py index 2d8b1ac40..688293509 100644 --- a/src/pyramid/interfaces.py +++ b/src/pyramid/interfaces.py @@ -1440,6 +1440,91 @@ class IPredicateList(Interface): """ Interface representing a predicate list """ +class IPredicateInfo(Interface): + package = Attribute( + 'The "current package" where the predicate ' + 'configuration statement was found' + ) + registry = Attribute( + 'The "current" application registry where the predicate was invoked' + ) + settings = Attribute( + 'The deployment settings dictionary related ' + 'to the current application' + ) + + def maybe_dotted(value): + """ Resolve the :term:`dotted Python name` ``dotted`` to a + global Python object. If ``dotted`` is not a string, return + it without attempting to do any name resolution. If + ``dotted`` is a relative dotted name (e.g. ``.foo.bar``, + consider it relative to the ``package``.""" + + +class IPredicateFactory(Interface): + def __call__(value, info): + """ + Create a a :class:`.IPredicate` instance for a specific value. + + """ + + +class IPredicate(Interface): + def text(): + """ + A textual description of the predicate used in the introspector. + + For example, ``'content_type = application/json'`` for a + ``ContentTypePredicate`` with a ``value == 'application/json'``. + + """ + + def phash(): + """ + A unique string for the predicate containing both the name and value. + + Often implementations simply set ``phash = text``. + + """ + + +class IRoutePredicate(IPredicate): + def __call__(info, request): + """ + The ``info`` object is a dictionary containing two keys: + + - "match" is a dictionary of parameters that becomes + ``request.matchdict`` if the route is selected + (all route predicates match). + + - "route" is the :class:`.IRoute` object being matched. + + Return ``True`` if the route should be selected or ``False`` otherwise. + + """ + + +class ISubscriberPredicate(IPredicate): + def __call__(*args): + """ + The ``args`` is usually just a single ``event`` argument sent to + ``registry.notify``. + + Return ``True`` if the subscriber should be executed for the given + arguments or ``False`` otherwise. + + """ + + +class IViewPredicate(IPredicate): + def __call__(context, request): + """ + Return ``True`` if the view should be selected for the given + arguments or ``False`` otherwise. + + """ + + class IViewDeriver(Interface): options = Attribute( 'A list of supported options to be passed to ' diff --git a/tests/test_config/test_predicates.py b/tests/test_config/test_predicates.py index c27b41639..f8abbbce4 100644 --- a/tests/test_config/test_predicates.py +++ b/tests/test_config/test_predicates.py @@ -476,5 +476,11 @@ class DummyRequest: class DummyConfigurator(object): + package = 'dummy package' + registry = 'dummy registry' + + def get_settings(self): + return {} + def maybe_dotted(self, thing): return thing |
