/usr/lib/python3/dist-packages/defer/utils.py is in python3-defer 1.0.6-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Utils for using deferreds with D-Bus."""
# Copyright (C) 2008-2010 Sebastian Heinlein <devel@glatzor.de>
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
__author__ = "Sebastian Heinlein <devel@glatzor.de>"
__all__ = ("dbus_deferred_method", "deferable")
from functools import wraps
import inspect
import dbus
from . import defer, Deferred, DeferredException
def dbus_deferred_method(*args, **kwargs):
"""Export the decorated method on the D-Bus and handle a maybe
returned Deferred.
This decorator can be applied to methods in the same way as the
@dbus.service.method method, but it correctly handles the case where
the method returns a Deferred.
This decorator was kindly taken from James Henstridge blog post and
adopted:
http://blogs.gnome.org/jamesh/2009/07/06/watching-iview-with-rygel/
"""
def decorator(function):
function = dbus.service.method(*args, **kwargs)(function)
@wraps(function)
def wrapper(*args, **kwargs):
def ignore_none_callback(*cb_args):
# The deferred method at least returns an tuple containing
# only None. Ignore this case.
if cb_args == (None,):
dbus_callback()
else:
dbus_callback(*cb_args)
dbus_callback = kwargs.pop('_dbus_callback')
dbus_errback = kwargs.pop('_dbus_errback')
deferred = defer(function, *args, **kwargs)
deferred.add_callback(ignore_none_callback)
deferred.add_errback(lambda error: dbus_errback(error.value))
# The @wraps decorator has copied over the attributes added by
# the @dbus.service.method decorator, but we need to manually
# set the async callback attributes.
wrapper._dbus_async_callbacks = ('_dbus_callback', '_dbus_errback')
return wrapper
return decorator
def deferable(func):
"""Add a defer attribute to the decorated function and return a Deferred
object. The callback of the Deferred will be passed as reply_handler
argument and the errback as the error_handler argument to the decorated
function.
This decorator allows to easily make use of Deferreds in a DBus client.
"""
@wraps(func)
def _deferable(*args, **kwargs):
def on_error(error, deferred):
# Make sure that we return a deferred exception
if isinstance(error, DeferredException):
deferred.errback(error)
else:
deferred.errback(DeferredException(error))
try:
# Check if the defer argument was specified
to_defer = kwargs.pop("defer")
except KeyError:
# Check if this function was called from an inline_callbacks
# decorated method
stack = inspect.stack()
try:
to_defer = stack[2][3] == "_inline_callbacks"
except IndexError:
to_defer = False
if to_defer:
deferred = Deferred()
kwargs["reply_handler"] = deferred.callback
kwargs["error_handler"] = lambda err: on_error(err, deferred)
func(*args, **kwargs)
return deferred
return func(*args, **kwargs)
return _deferable
# vim:tw=4:sw=4:et
|