Merge pull request #824 from OOPMan/master-decorator-improvements

Register/Subscribe Decorator Improvements
This commit is contained in:
Tobias Oberstein
2017-04-19 10:52:31 +02:00
committed by GitHub
3 changed files with 99 additions and 18 deletions

View File

@@ -1310,9 +1310,14 @@ class ApplicationSession(BaseSession):
if "_wampuris" in proc.__dict__:
for pat in proc.__dict__["_wampuris"]:
if pat.is_handler():
uri = pat.uri()
subopts = options or pat.subscribe_options()
on_replies.append(_subscribe(handler, proc, uri, subopts))
_uri = pat.uri()
subopts = pat.options or options
if subopts is None:
if pat.uri_type == uri.Pattern.URI_TYPE_WILDCARD:
subopts = types.SubscribeOptions(match=u"wildcard")
else:
subopts = types.SubscribeOptions(match=u"exact")
on_replies.append(_subscribe(handler, proc, _uri, subopts))
# XXX needs coverage
return txaio.gather(on_replies, consume_exceptions=True)
@@ -1470,8 +1475,9 @@ class ApplicationSession(BaseSession):
if "_wampuris" in proc.__dict__:
for pat in proc.__dict__["_wampuris"]:
if pat.is_endpoint():
uri = pat.uri()
on_replies.append(_register(endpoint, proc, uri, options))
_uri = pat.uri()
regopts = pat.options or options
on_replies.append(_register(endpoint, proc, _uri, regopts))
# XXX neds coverage
return txaio.gather(on_replies, consume_exceptions=True)

View File

@@ -27,7 +27,7 @@
from __future__ import absolute_import
from autobahn import wamp
from autobahn.wamp.uri import Pattern
from autobahn.wamp.uri import Pattern, RegisterOptions, SubscribeOptions
import unittest2 as unittest
@@ -141,6 +141,24 @@ class TestDecorators(unittest.TestCase):
self.assertEqual(update._wampuris[0].uri(), u"com.myapp.<category:string>.<cid:int>.update")
self.assertEqual(update._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
@wamp.register(u"com.myapp.circle.<name:string>",
RegisterOptions(match=u"wildcard", details_arg="details"))
def circle(name=None, details=None):
""" Do nothing. """
self.assertTrue(hasattr(circle, '_wampuris'))
self.assertTrue(type(circle._wampuris) == list)
self.assertEqual(len(circle._wampuris), 1)
self.assertIsInstance(circle._wampuris[0], Pattern)
self.assertIsInstance(circle._wampuris[0].options, RegisterOptions)
self.assertEqual(circle._wampuris[0].options.match, u"wildcard")
self.assertEqual(circle._wampuris[0].options.details_arg, "details")
self.assertTrue(circle._wampuris[0].is_endpoint())
self.assertFalse(circle._wampuris[0].is_handler())
self.assertFalse(circle._wampuris[0].is_exception())
self.assertEqual(circle._wampuris[0].uri(), u"com.myapp.circle.<name:string>")
self.assertEqual(circle._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
def test_decorate_handler(self):
@wamp.subscribe(u"com.myapp.on_shutdown")
@@ -185,6 +203,24 @@ class TestDecorators(unittest.TestCase):
self.assertEqual(on_update._wampuris[0].uri(), u"com.myapp.<category:string>.<cid:int>.on_update")
self.assertEqual(on_update._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
@wamp.subscribe(u"com.myapp.on.<event:string>",
SubscribeOptions(match=u"wildcard", details_arg="details"))
def on_event(event=None, details=None):
""" Do nothing. """
self.assertTrue(hasattr(on_event, '_wampuris'))
self.assertTrue(type(on_event._wampuris) == list)
self.assertEqual(len(on_event._wampuris), 1)
self.assertIsInstance(on_event._wampuris[0], Pattern)
self.assertIsInstance(on_event._wampuris[0].options, SubscribeOptions)
self.assertEqual(on_event._wampuris[0].options.match, u"wildcard")
self.assertEqual(on_event._wampuris[0].options.details_arg, "details")
self.assertFalse(on_event._wampuris[0].is_endpoint())
self.assertTrue(on_event._wampuris[0].is_handler())
self.assertFalse(on_event._wampuris[0].is_exception())
self.assertEqual(on_event._wampuris[0].uri(), u"com.myapp.on.<event:string>")
self.assertEqual(on_event._wampuris[0]._type, Pattern.URI_TYPE_WILDCARD)
def test_decorate_exception(self):
@wamp.error(u"com.myapp.error")

View File

@@ -28,10 +28,11 @@
from __future__ import absolute_import
import re
import six
from autobahn.util import public
from autobahn.wamp.types import SubscribeOptions
from autobahn.wamp.types import RegisterOptions, SubscribeOptions
__all__ = (
'Pattern',
@@ -132,7 +133,7 @@ class Pattern(object):
This pattern is stricter than a general WAMP URI component since a valid Python identifier is required.
"""
def __init__(self, uri, target):
def __init__(self, uri, target, options=None):
"""
:param uri: The URI or URI pattern, e.g. ``"com.myapp.product.<product:int>.update"``.
@@ -141,11 +142,20 @@ class Pattern(object):
:param target: The target for this pattern: a procedure endpoint (a callable),
an event handler (a callable) or an exception (a class).
:type target: callable or obj
:param options: An optional options object
:type options: None or RegisterOptions or SubscribeOptions
"""
assert(type(uri) == six.text_type)
assert(target in [Pattern.URI_TARGET_ENDPOINT,
Pattern.URI_TARGET_HANDLER,
Pattern.URI_TARGET_EXCEPTION])
if target == Pattern.URI_TARGET_ENDPOINT:
assert(options is None or type(options) == RegisterOptions)
elif target == Pattern.URI_TARGET_HANDLER:
assert(options is None or type(options) == SubscribeOptions)
else:
options = None
components = uri.split('.')
pl = []
@@ -207,6 +217,29 @@ class Pattern(object):
self._names = None
self._uri = uri
self._target = target
self._options = options
@public
@property
def options(self):
"""
Returns the Options instance (if present) for this pattern.
:return: None or the Options instance
:rtype: None or RegisterOptions or SubscribeOptions
"""
return self._options
@public
@property
def uri_type(self):
"""
Returns the URI type of this pattern
:return:
:rtype: Pattern.URI_TYPE_EXACT, Pattern.URI_TYPE_PREFIX or Pattern.URI_TYPE_WILDCARD
"""
return self._type
@public
def uri(self):
@@ -218,12 +251,6 @@ class Pattern(object):
"""
return self._uri
def subscribe_options(self):
if self._type == Pattern.URI_TYPE_WILDCARD:
return SubscribeOptions(match=u"wildcard")
else:
return SubscribeOptions(match=u"exact")
def match(self, uri):
"""
Match the given (fully qualified) URI according to this pattern
@@ -282,29 +309,41 @@ class Pattern(object):
@public
def register(uri):
def register(uri, options=None):
"""
Decorator for WAMP procedure endpoints.
:param uri:
:type uri: str
:param options:
:type options: None or RegisterOptions
"""
def decorate(f):
assert(callable(f))
if not hasattr(f, '_wampuris'):
f._wampuris = []
f._wampuris.append(Pattern(uri, Pattern.URI_TARGET_ENDPOINT))
f._wampuris.append(Pattern(uri, Pattern.URI_TARGET_ENDPOINT, options))
return f
return decorate
@public
def subscribe(uri):
def subscribe(uri, options=None):
"""
Decorator for WAMP event handlers.
:param uri:
:type uri: str
:param options:
:type options: None or SubscribeOptions
"""
def decorate(f):
assert(callable(f))
if not hasattr(f, '_wampuris'):
f._wampuris = []
f._wampuris.append(Pattern(uri, Pattern.URI_TARGET_HANDLER))
f._wampuris.append(Pattern(uri, Pattern.URI_TARGET_HANDLER, options))
return f
return decorate