123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- """Functional utilities."""
- from __future__ import absolute_import, unicode_literals
- from .abstract import Thenable
- from .promises import promise
- __all__ = [
- 'maybe_promise', 'ensure_promise',
- 'ppartial', 'preplace', 'ready_promise',
- 'starpromise', 'transform', 'wrap',
- ]
- def maybe_promise(p):
- """Return None if p is unefined, otherwise make sure it's a promise."""
- if p:
- if not isinstance(p, Thenable):
- return promise(p)
- return p
- def ensure_promise(p):
- """Ensure p is a promise.
- If p is not a promise, a new promise is created with p' as callback.
- """
- if p is None:
- return promise()
- return maybe_promise(p)
- def ppartial(p, *args, **kwargs):
- """Create/modify promise with partial arguments."""
- p = ensure_promise(p)
- if args:
- p.args = args + p.args
- if kwargs:
- p.kwargs.update(kwargs)
- return p
- def preplace(p, *args, **kwargs):
- """Replace promise arguments.
- This will force the promise to disregard any arguments
- the promise is fulfilled with, and to be called with the
- provided arguments instead.
- """
- def _replacer(*_, **__):
- return p(*args, **kwargs)
- return promise(_replacer)
- def ready_promise(callback=None, *args):
- """Create promise that is already fulfilled."""
- p = ensure_promise(callback)
- p(*args)
- return p
- def starpromise(fun, *args, **kwargs):
- """Create promise, using star arguments."""
- return promise(fun, args, kwargs)
- def transform(filter_, callback, *filter_args, **filter_kwargs):
- """Filter final argument to a promise.
- E.g. to coerce callback argument to :class:`int`::
- transform(int, callback)
- or a more complex example extracting something from a dict
- and coercing the value to :class:`float`:
- .. code-block:: python
- def filter_key_value(key, filter_, mapping):
- return filter_(mapping[key])
- def get_page_expires(self, url, callback=None):
- return self.request(
- 'GET', url,
- callback=transform(get_key, callback, 'PageExpireValue', int),
- )
- """
- callback = ensure_promise(callback)
- P = promise(_transback, (filter_, callback, filter_args, filter_kwargs))
- P.then(promise(), callback.throw)
- return P
- def _transback(filter_, callback, args, kwargs, ret):
- try:
- ret = filter_(*args + (ret,), **kwargs)
- except Exception:
- callback.throw()
- else:
- return callback(ret)
- def wrap(p):
- """Wrap promise.
- This wraps the promise such that if the promise is called with a promise as
- argument, we attach ourselves to that promise instead.
- """
- def on_call(*args, **kwargs):
- if len(args) == 1 and isinstance(args[0], promise):
- return args[0].then(p)
- else:
- return p(*args, **kwargs)
- return on_call
|