summaryrefslogtreecommitdiff
path: root/slixmpp/stanza
diff options
context:
space:
mode:
authormathieui <mathieui@mathieui.net>2015-02-28 13:34:52 +0100
committermathieui <mathieui@mathieui.net>2015-02-28 19:02:35 +0100
commitbf5d7c83af320b7af629857aab7060302abfabf5 (patch)
tree548e088aae38c780300b7f10fc7eec092db33a1a /slixmpp/stanza
parentc66a4d4097a249efc029b761d6150378a54bf702 (diff)
downloadslixmpp-bf5d7c83af320b7af629857aab7060302abfabf5.tar.gz
slixmpp-bf5d7c83af320b7af629857aab7060302abfabf5.tar.bz2
slixmpp-bf5d7c83af320b7af629857aab7060302abfabf5.tar.xz
slixmpp-bf5d7c83af320b7af629857aab7060302abfabf5.zip
Change the API to make iq.send() always return a future
remove coroutine_wrapper, add a future_wrapper (which is only needed when the result stanza can be cached). Update the documentation as well.
Diffstat (limited to 'slixmpp/stanza')
-rw-r--r--slixmpp/stanza/iq.py118
1 files changed, 41 insertions, 77 deletions
diff --git a/slixmpp/stanza/iq.py b/slixmpp/stanza/iq.py
index f7b222e6..2730314f 100644
--- a/slixmpp/stanza/iq.py
+++ b/slixmpp/stanza/iq.py
@@ -152,59 +152,15 @@ class Iq(RootStanza):
new_iq['type'] = 'result'
return new_iq
- @asyncio.coroutine
- def _send_coroutine(self, matcher=None, timeout=None):
- """Send an <iq> stanza over the XML stream.
-
- Blocks (with asyncio) until a the reply is received.
- Use with yield from iq.send(coroutine=True).
-
- Overrides StanzaBase.send
-
- :param int timeout: The length of time (in seconds) to wait for a
- response before an IqTimeout is raised
- """
-
- future = asyncio.Future()
-
- def callback(result):
- future.set_result(result)
-
- def callback_timeout():
- future.set_result(None)
-
- handler_name = 'IqCallback_%s' % self['id']
-
- if timeout:
- self.callback = callback
- self.stream.schedule('IqTimeout_%s' % self['id'],
- timeout,
- callback_timeout,
- repeat=False)
- handler = Callback(handler_name,
- matcher,
- self._handle_result,
- once=True)
- else:
- handler = Callback(handler_name,
- matcher,
- callback,
- once=True)
- self.stream.register_handler(handler)
- StanzaBase.send(self)
- result = yield from future
- if result is None:
- raise IqTimeout(self)
- if result['type'] == 'error':
- raise IqError(result)
- return result
-
def send(self, callback=None, timeout=None, timeout_callback=None, coroutine=False):
"""Send an <iq> stanza over the XML stream.
A callback handler can be provided that will be executed when the Iq
stanza's result reply is received.
+ Returns a future which result will be set to the result Iq if it is of type 'get' or 'set'
+ (when it is received), or a future with the result set to None if it has another type.
+
Overrides StanzaBase.send
:param function callback: Optional reference to a stream handler
@@ -218,8 +174,7 @@ class Iq(RootStanza):
timeout expires before a response has
been received for the originally-sent
IQ stanza.
- :param bool coroutine: This function will return a coroutine if this
- argument is True.
+ :rtype: asyncio.Future
"""
if self.stream.session_bind_event.is_set():
matcher = MatchIDSender({
@@ -230,36 +185,45 @@ class Iq(RootStanza):
else:
matcher = MatcherId(self['id'])
- if not coroutine:
- if callback is not None and self['type'] in ('get', 'set'):
- handler_name = 'IqCallback_%s' % self['id']
- if asyncio.iscoroutinefunction(callback):
- constr = CoroutineCallback
- else:
- constr = Callback
- if timeout_callback:
- self.callback = callback
- self.timeout_callback = timeout_callback
- self.stream.schedule('IqTimeout_%s' % self['id'],
- timeout,
- self._fire_timeout,
- repeat=False)
- handler = constr(handler_name,
- matcher,
- self._handle_result,
- once=True)
- else:
- handler = constr(handler_name,
- matcher,
- callback,
- once=True)
- self.stream.register_handler(handler)
- StanzaBase.send(self)
- return handler_name
+ future = asyncio.Future()
+
+ def callback_success(result):
+ if result['type'] == 'error':
+ future.set_exception(IqError(result))
else:
- return StanzaBase.send(self)
+ future.set_result(result)
+
+ if timeout_callback is not None and timeout is not None:
+ self.stream.cancel_schedule('IqTimeout_%s' % self['id'])
+ if callback is not None:
+ callback(result)
+
+ def callback_timeout():
+ future.set_exception(IqTimeout(self))
+ self.stream.remove_handler('IqCallback_%s' % self['id'])
+ if timeout_callback is not None:
+ timeout_callback(self)
+
+ if self['type'] in ('get', 'set'):
+ handler_name = 'IqCallback_%s' % self['id']
+ if asyncio.iscoroutinefunction(callback):
+ constr = CoroutineCallback
+ else:
+ constr = Callback
+ if timeout_callback is not None and timeout is not None:
+ self.stream.schedule('IqTimeout_%s' % self['id'],
+ timeout,
+ callback_timeout,
+ repeat=False)
+ handler = constr(handler_name,
+ matcher,
+ callback_success,
+ once=True)
+ self.stream.register_handler(handler)
else:
- return self._send_coroutine(timeout=timeout, matcher=matcher)
+ future.set_result(None)
+ StanzaBase.send(self)
+ return future
def _handle_result(self, iq):
# we got the IQ, so don't fire the timeout