Blame dbus/_dbus.py

Packit 130fc8
"""Implementation for dbus.Bus. Not to be imported directly."""
Packit 130fc8
Packit 130fc8
# Copyright (C) 2003, 2004, 2005, 2006 Red Hat Inc. <http://www.redhat.com/>
Packit 130fc8
# Copyright (C) 2003 David Zeuthen
Packit 130fc8
# Copyright (C) 2004 Rob Taylor
Packit 130fc8
# Copyright (C) 2005, 2006 Collabora Ltd. <http://www.collabora.co.uk/>
Packit 130fc8
#
Packit 130fc8
# Permission is hereby granted, free of charge, to any person
Packit 130fc8
# obtaining a copy of this software and associated documentation
Packit 130fc8
# files (the "Software"), to deal in the Software without
Packit 130fc8
# restriction, including without limitation the rights to use, copy,
Packit 130fc8
# modify, merge, publish, distribute, sublicense, and/or sell copies
Packit 130fc8
# of the Software, and to permit persons to whom the Software is
Packit 130fc8
# furnished to do so, subject to the following conditions:
Packit 130fc8
#
Packit 130fc8
# The above copyright notice and this permission notice shall be
Packit 130fc8
# included in all copies or substantial portions of the Software.
Packit 130fc8
#
Packit 130fc8
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Packit 130fc8
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit 130fc8
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Packit 130fc8
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
Packit 130fc8
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
Packit 130fc8
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Packit 130fc8
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Packit 130fc8
# DEALINGS IN THE SOFTWARE.
Packit 130fc8
Packit 130fc8
from __future__ import generators
Packit 130fc8
Packit 130fc8
__all__ = ('Bus', 'SystemBus', 'SessionBus', 'StarterBus')
Packit 130fc8
__docformat__ = 'reStructuredText'
Packit 130fc8
Packit 130fc8
from dbus.exceptions import DBusException
Packit 130fc8
from _dbus_bindings import (
Packit 130fc8
    BUS_DAEMON_IFACE, BUS_DAEMON_NAME, BUS_DAEMON_PATH, BUS_SESSION,
Packit 130fc8
    BUS_STARTER, BUS_SYSTEM, DBUS_START_REPLY_ALREADY_RUNNING,
Packit 130fc8
    DBUS_START_REPLY_SUCCESS, validate_bus_name,
Packit 130fc8
    validate_interface_name, validate_member_name, validate_object_path)
Packit 130fc8
from dbus.bus import BusConnection
Packit 130fc8
from dbus.lowlevel import SignalMessage
Packit 130fc8
from dbus._compat import is_py2
Packit 130fc8
Packit 130fc8
if is_py2:
Packit 130fc8
    from _dbus_bindings import UTF8String
Packit 130fc8
Packit 130fc8
Packit 130fc8
class Bus(BusConnection):
Packit 130fc8
    """A connection to one of three possible standard buses, the SESSION,
Packit 130fc8
    SYSTEM, or STARTER bus. This class manages shared connections to those
Packit 130fc8
    buses.
Packit 130fc8
Packit 130fc8
    If you're trying to subclass `Bus`, you may be better off subclassing
Packit 130fc8
    `BusConnection`, which doesn't have all this magic.
Packit 130fc8
    """
Packit 130fc8
Packit 130fc8
    _shared_instances = {}
Packit 130fc8
Packit 130fc8
    def __new__(cls, bus_type=BusConnection.TYPE_SESSION, private=False,
Packit 130fc8
                mainloop=None):
Packit 130fc8
        """Constructor, returning an existing instance where appropriate.
Packit 130fc8
Packit 130fc8
        The returned instance is actually always an instance of `SessionBus`,
Packit 130fc8
        `SystemBus` or `StarterBus`.
Packit 130fc8
Packit 130fc8
        :Parameters:
Packit 130fc8
            `bus_type` : cls.TYPE_SESSION, cls.TYPE_SYSTEM or cls.TYPE_STARTER
Packit 130fc8
                Connect to the appropriate bus
Packit 130fc8
            `private` : bool
Packit 130fc8
                If true, never return an existing shared instance, but instead
Packit 130fc8
                return a private connection.
Packit 130fc8
Packit 130fc8
                :Deprecated: since 0.82.3. Use dbus.bus.BusConnection for
Packit 130fc8
                    private connections.
Packit 130fc8
Packit 130fc8
            `mainloop` : dbus.mainloop.NativeMainLoop
Packit 130fc8
                The main loop to use. The default is to use the default
Packit 130fc8
                main loop if one has been set up, or raise an exception
Packit 130fc8
                if none has been.
Packit 130fc8
        :Changed: in dbus-python 0.80:
Packit 130fc8
            converted from a wrapper around a Connection to a Connection
Packit 130fc8
            subclass.
Packit 130fc8
        """
Packit 130fc8
        if (not private and bus_type in cls._shared_instances):
Packit 130fc8
            return cls._shared_instances[bus_type]
Packit 130fc8
Packit 130fc8
        # this is a bit odd, but we create instances of the subtypes
Packit 130fc8
        # so we can return the shared instances if someone tries to
Packit 130fc8
        # construct one of them (otherwise we'd eg try and return an
Packit 130fc8
        # instance of Bus from __new__ in SessionBus). why are there
Packit 130fc8
        # three ways to construct this class? we just don't know.
Packit 130fc8
        if bus_type == BUS_SESSION:
Packit 130fc8
            subclass = SessionBus
Packit 130fc8
        elif bus_type == BUS_SYSTEM:
Packit 130fc8
            subclass = SystemBus
Packit 130fc8
        elif bus_type == BUS_STARTER:
Packit 130fc8
            subclass = StarterBus
Packit 130fc8
        else:
Packit 130fc8
            raise ValueError('invalid bus_type %s' % bus_type)
Packit 130fc8
Packit 130fc8
        bus = BusConnection.__new__(subclass, bus_type, mainloop=mainloop)
Packit 130fc8
Packit 130fc8
        bus._bus_type = bus_type
Packit 130fc8
Packit 130fc8
        if not private:
Packit 130fc8
            cls._shared_instances[bus_type] = bus
Packit 130fc8
Packit 130fc8
        return bus
Packit 130fc8
Packit 130fc8
    def close(self):
Packit 130fc8
        t = self._bus_type
Packit 130fc8
        if self.__class__._shared_instances.get(t) is self:
Packit 130fc8
            del self.__class__._shared_instances[t]
Packit 130fc8
        super(Bus, self).close()
Packit 130fc8
Packit 130fc8
    def get_connection(self):
Packit 130fc8
        """Return self, for backwards compatibility with earlier dbus-python
Packit 130fc8
        versions where Bus was not a subclass of Connection.
Packit 130fc8
Packit 130fc8
        :Deprecated: since 0.80.0
Packit 130fc8
        """
Packit 130fc8
        return self
Packit 130fc8
    _connection = property(get_connection, None, None,
Packit 130fc8
                           """self._connection == self, for backwards
Packit 130fc8
                           compatibility with earlier dbus-python versions
Packit 130fc8
                           where Bus was not a subclass of Connection.""")
Packit 130fc8
Packit 130fc8
    def get_session(private=False):
Packit 130fc8
        """Static method that returns a connection to the session bus.
Packit 130fc8
Packit 130fc8
        :Parameters:
Packit 130fc8
            `private` : bool
Packit 130fc8
                If true, do not return a shared connection.
Packit 130fc8
        """
Packit 130fc8
        return SessionBus(private=private)
Packit 130fc8
Packit 130fc8
    get_session = staticmethod(get_session)
Packit 130fc8
Packit 130fc8
    def get_system(private=False):
Packit 130fc8
        """Static method that returns a connection to the system bus.
Packit 130fc8
Packit 130fc8
        :Parameters:
Packit 130fc8
            `private` : bool
Packit 130fc8
                If true, do not return a shared connection.
Packit 130fc8
        """
Packit 130fc8
        return SystemBus(private=private)
Packit 130fc8
Packit 130fc8
    get_system = staticmethod(get_system)
Packit 130fc8
Packit 130fc8
Packit 130fc8
    def get_starter(private=False):
Packit 130fc8
        """Static method that returns a connection to the starter bus.
Packit 130fc8
Packit 130fc8
        :Parameters:
Packit 130fc8
            `private` : bool
Packit 130fc8
                If true, do not return a shared connection.
Packit 130fc8
        """
Packit 130fc8
        return StarterBus(private=private)
Packit 130fc8
Packit 130fc8
    get_starter = staticmethod(get_starter)
Packit 130fc8
Packit 130fc8
    def __repr__(self):
Packit 130fc8
        if self._bus_type == BUS_SESSION:
Packit 130fc8
            name = 'session'
Packit 130fc8
        elif self._bus_type == BUS_SYSTEM:
Packit 130fc8
            name = 'system'
Packit 130fc8
        elif self._bus_type == BUS_STARTER:
Packit 130fc8
            name = 'starter'
Packit 130fc8
        else:
Packit 130fc8
            name = 'unknown bus type'
Packit 130fc8
Packit 130fc8
        return '<%s.%s (%s) at %#x>' % (self.__class__.__module__,
Packit 130fc8
                                        self.__class__.__name__,
Packit 130fc8
                                        name, id(self))
Packit 130fc8
    __str__ = __repr__
Packit 130fc8
Packit 130fc8
Packit 130fc8
# FIXME: Drop the subclasses here? I can't think why we'd ever want
Packit 130fc8
# polymorphism
Packit 130fc8
class SystemBus(Bus):
Packit 130fc8
    """The system-wide message bus."""
Packit 130fc8
    def __new__(cls, private=False, mainloop=None):
Packit 130fc8
        """Return a connection to the system bus.
Packit 130fc8
Packit 130fc8
        :Parameters:
Packit 130fc8
            `private` : bool
Packit 130fc8
                If true, never return an existing shared instance, but instead
Packit 130fc8
                return a private connection.
Packit 130fc8
            `mainloop` : dbus.mainloop.NativeMainLoop
Packit 130fc8
                The main loop to use. The default is to use the default
Packit 130fc8
                main loop if one has been set up, or raise an exception
Packit 130fc8
                if none has been.
Packit 130fc8
        """
Packit 130fc8
        return Bus.__new__(cls, Bus.TYPE_SYSTEM, mainloop=mainloop,
Packit 130fc8
                           private=private)
Packit 130fc8
Packit 130fc8
class SessionBus(Bus):
Packit 130fc8
    """The session (current login) message bus."""
Packit 130fc8
    def __new__(cls, private=False, mainloop=None):
Packit 130fc8
        """Return a connection to the session bus.
Packit 130fc8
Packit 130fc8
        :Parameters:
Packit 130fc8
            `private` : bool
Packit 130fc8
                If true, never return an existing shared instance, but instead
Packit 130fc8
                return a private connection.
Packit 130fc8
            `mainloop` : dbus.mainloop.NativeMainLoop
Packit 130fc8
                The main loop to use. The default is to use the default
Packit 130fc8
                main loop if one has been set up, or raise an exception
Packit 130fc8
                if none has been.
Packit 130fc8
        """
Packit 130fc8
        return Bus.__new__(cls, Bus.TYPE_SESSION, private=private,
Packit 130fc8
                           mainloop=mainloop)
Packit 130fc8
Packit 130fc8
class StarterBus(Bus):
Packit 130fc8
    """The bus that activated this process (only valid if
Packit 130fc8
    this process was launched by DBus activation).
Packit 130fc8
    """
Packit 130fc8
    def __new__(cls, private=False, mainloop=None):
Packit 130fc8
        """Return a connection to the bus that activated this process.
Packit 130fc8
Packit 130fc8
        :Parameters:
Packit 130fc8
            `private` : bool
Packit 130fc8
                If true, never return an existing shared instance, but instead
Packit 130fc8
                return a private connection.
Packit 130fc8
            `mainloop` : dbus.mainloop.NativeMainLoop
Packit 130fc8
                The main loop to use. The default is to use the default
Packit 130fc8
                main loop if one has been set up, or raise an exception
Packit 130fc8
                if none has been.
Packit 130fc8
        """
Packit 130fc8
        return Bus.__new__(cls, Bus.TYPE_STARTER, private=private,
Packit 130fc8
                           mainloop=mainloop)