Skip to content

Commit

Permalink
Merge pull request #8 from zopefoundation/grok-order-decorator
Browse files Browse the repository at this point in the history
Allow grok.order to be used as a decorator. Properly sort subscriptions.
  • Loading branch information
thefunny42 committed Oct 24, 2017
2 parents fd38eb8 + e8f053b commit 9f0ef71
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 8 deletions.
8 changes: 7 additions & 1 deletion CHANGES.txt
Expand Up @@ -4,7 +4,13 @@ Changes
2.5.2 (unreleased)
------------------

- Nothing changed yet.
- Make ``grok.order()`` usable as a decorator on functions so they can
be sorted as well.

- Make ``grok.queryOrderedSubscriptions`` and
``grok.queryOrderedMultiSubscriptions`` sort the subscriptions
themselves and not the result returned by them. This let you for
instance sort events-type subscriptions.


2.5.1 (2016-02-24)
Expand Down
10 changes: 9 additions & 1 deletion src/grokcore/component/directive.py
Expand Up @@ -13,6 +13,7 @@
##############################################################################
"""Grok directives.
"""
import sys
import martian
import martian.util
from martian.error import GrokError, GrokImportError
Expand Down Expand Up @@ -139,7 +140,7 @@ class direct(martian.MarkerDirective):
scope = martian.CLASS

class order(martian.Directive):
scope = martian.CLASS
scope = martian.CLASS_OR_MODULE
store = martian.ONCE
default = 0, 0

Expand All @@ -149,6 +150,13 @@ def factory(self, value=0):
order._order += 1
return value, order._order

def __call__(self, func):
frame = sys._getframe(1)
name = self.dotted_name()
value = frame.f_locals.pop(name)
self.set(func, value)
return func

class path(martian.Directive):
scope = martian.CLASS
store = martian.ONCE
Expand Down
22 changes: 19 additions & 3 deletions src/grokcore/component/subscription.py
Expand Up @@ -13,11 +13,19 @@
##############################################################################
"""Grok subscriptions functions.
"""
from zope import component
from zope.interface import providedBy
from grokcore.component import util

def queryOrderedMultiSubscriptions(components, interface):
return util.sort_components(component.subscribers(components, interface))
manager = util.getSiteManager()
subscriptions = manager.adapters.subscriptions(
map(providedBy, components), interface)
results = []
for subscription in util.sort_components(subscriptions):
result = subscription(*components)
if result is not None:
results.append(result)
return results

def queryOrderedSubscriptions(component, interface):
return queryOrderedMultiSubscriptions((component, ), interface)
Expand All @@ -29,7 +37,15 @@ def queryMultiSubscriptions(components, interface):
:parameter interface: interface that the subscriptions should provide.
:return: a list of subscriptions.
"""
return component.subscribers(components, interface)
manager = util.getSiteManager()
subscriptions = manager.adapters.subscriptions(
map(providedBy, components), interface)
results = []
for subscription in subscriptions:
result = subscription(*components)
if result is not None:
results.append(result)
return results

def querySubscriptions(component, interface):
"""Query for subscriptions on `component` providing `interface`.
Expand Down
11 changes: 8 additions & 3 deletions src/grokcore/component/tests/order/combined_orderdirective.py
Expand Up @@ -4,22 +4,23 @@
have the order specified, then the order will be determined by first
sorting on the order specified, and then by the definition order.
>>> components = [First(), Second(), Third(), Fourth(), Fifth()]
>>> components = [First(), Second(), Third, Fourth(), Fifth(), six]
>>> from grokcore.component import sort_components
>>> sort_components(components)
[<...Third object at ...>,
[<class '...Third'>,
<...Fourth object at ...>,
<...Second object at ...>,
<...Fifth object at ...>,
<function six at ...>,
<...First object at ...>]
"""

import grokcore.component as grok

class First(object):
grok.order(2)
grok.order(5)

class Second(object):
grok.order(1)
Expand All @@ -32,3 +33,7 @@ class Fourth(object):

class Fifth(object):
grok.order(1)

@grok.order(2)
def six():
pass

0 comments on commit 9f0ef71

Please sign in to comment.