[PATCH 02/17] Remove BusImplementation, removing its remaining functionality to Connection.

John (J5) Palmieri johnp at redhat.com
Mon Apr 30 14:36:50 PDT 2007


Looks good.

On Mon, 2007-04-30 at 11:23 +0100, Simon McVittie wrote:
> * Move get_unique_name to Connection (it can be useful for connections which
>   aren't to a real bus daemon but partially emulate one, like Telepathy's
>   Tubes)
> * Add set_unique_name to Connection (same reason)
> * Convert BusImplementation.__new__ into Connection._new_for_bus
> * Have dbus.Bus subclass _dbus_bindings.Connection directly
> 
> diff --git a/_dbus_bindings/bus.c b/_dbus_bindings/bus.c
> index 761b67e..1e3b81f 100644
> --- a/_dbus_bindings/bus.c
> +++ b/_dbus_bindings/bus.c
> @@ -23,26 +23,8 @@
>  #include "dbus_bindings-internal.h"
>  #include "conn-internal.h"
>  
> -PyDoc_STRVAR(Bus_tp_doc,
> -"If the address is an int it must be one of the constants BUS_SESSION,\n"
> -"BUS_SYSTEM, BUS_STARTER; if a string, it must be a D-Bus address.\n"
> -"The default is BUS_SESSION.\n"
> -"\n"
> -"Constructor::\n"
> -"\n"
> -"   BusImplementation([address: str or int])\n"
> -);
> -
> -/* Bus definition =================================================== */
> -
> -static PyTypeObject BusType;
> -
> -#define Bus_Check(ob) PyObject_TypeCheck(ob, &BusType)
> -
> -/* Bus methods ====================================================== */
> -
> -static PyObject *
> -Bus_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
> +PyObject *
> +DBusPyConnection_NewForBus(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
>  {
>      PyObject *first = NULL, *mainloop = NULL;
>      DBusConnection *conn;
> @@ -110,11 +92,8 @@ Bus_tp_new(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
>      return DBusPyConnection_NewConsumingDBusConnection(cls, conn, mainloop);
>  }
>  
> -PyDoc_STRVAR(Bus_get_unique_name__doc__,
> -"get_unique_name() -> str\n\n"
> -"Return this application's unique name on this bus.\n");
> -static PyObject *
> -Bus_get_unique_name(Connection *self, PyObject *args UNUSED)
> +PyObject *
> +DBusPyConnection_GetUniqueName(Connection *self, PyObject *args UNUSED)
>  {
>      const char *name;
>  
> @@ -124,81 +103,50 @@ Bus_get_unique_name(Connection *self, PyObject *args UNUSED)
>      name = dbus_bus_get_unique_name(self->conn);
>      Py_END_ALLOW_THREADS
>      if (!name) {
> -        /* shouldn't happen, but C subtypes could have done something stupid */
> -        PyErr_SetString(DBusPyException, "Unable to retrieve unique name");
> +        PyErr_SetString(DBusPyException, "This connection has no unique "
> +                        "name yet");
>          return NULL;
>      }
>      return PyString_FromString(name);
>  }
>  
> -/* Bus type object ================================================== */
> -
> -static struct PyMethodDef Bus_tp_methods[] = {
> -#define ENTRY(name, flags) {#name, (PyCFunction)Bus_##name, flags, Bus_##name##__doc__},
> -    ENTRY(get_unique_name, METH_NOARGS)
> -#undef ENTRY
> -    {NULL},
> -};
> -
> -static PyTypeObject BusType = {
> -        PyObject_HEAD_INIT(NULL)
> -        0,                      /*ob_size*/
> -        "_dbus_bindings.BusImplementation",  /*tp_name*/
> -        0,                      /*tp_basicsize*/
> -        0,                      /*tp_itemsize*/
> -        /* methods */
> -        0,                      /*tp_dealloc*/
> -        0,                      /*tp_print*/
> -        0,                      /*tp_getattr*/
> -        0,                      /*tp_setattr*/
> -        0,                      /*tp_compare*/
> -        0,                      /*tp_repr*/
> -        0,                      /*tp_as_number*/
> -        0,                      /*tp_as_sequence*/
> -        0,                      /*tp_as_mapping*/
> -        0,                      /*tp_hash*/
> -        0,                      /*tp_call*/
> -        0,                      /*tp_str*/
> -        0,                      /*tp_getattro*/
> -        0,                      /*tp_setattro*/
> -        0,                      /*tp_as_buffer*/
> -        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /*tp_flags*/
> -        Bus_tp_doc,             /*tp_doc*/
> -        0,                      /*tp_traverse*/
> -        0,                      /*tp_clear*/
> -        0,                      /*tp_richcompare*/
> -        0,                      /*tp_weaklistoffset*/
> -        0,                      /*tp_iter*/
> -        0,                      /*tp_iternext*/
> -        Bus_tp_methods,         /*tp_methods*/
> -        0,                      /*tp_members*/
> -        0,                      /*tp_getset*/
> -        DEFERRED_ADDRESS(&ConnectionType), /*tp_base*/
> -        0,                      /*tp_dict*/
> -        0,                      /*tp_descr_get*/
> -        0,                      /*tp_descr_set*/
> -        0,                      /*tp_dictoffset*/
> -        0,                      /*tp_init*/
> -        0,                      /*tp_alloc*/
> -        Bus_tp_new,             /*tp_new*/
> -        0,                      /*tp_free*/
> -        0,                      /*tp_is_gc*/
> -};
> -
> -dbus_bool_t
> -dbus_py_init_bus_types(void)
> +PyObject *
> +DBusPyConnection_SetUniqueName(Connection *self, PyObject *args)
>  {
> -    BusType.tp_base = &DBusPyConnection_Type;
> -    if (PyType_Ready(&BusType) < 0) return 0;
> -    return 1;
> -}
> +    const char *old_name, *new_name;
>  
> -dbus_bool_t
> -dbus_py_insert_bus_types(PyObject *this_module)
> -{
> -    if (PyModule_AddObject(this_module, "BusImplementation",
> -                           (PyObject *)&BusType) < 0) return 0;
> -    return 1;
> +    if (!PyArg_ParseTuple(args, "s:set_unique_name", &new_name)) {
> +        return NULL;
> +    }
> +
> +    TRACE(self);
> +    DBUS_PY_RAISE_VIA_NULL_IF_FAIL(self->conn);
> +
> +    /* libdbus will assert if we try to set a unique name when there's
> +     * already one, so we need to make sure that can't happen.
> +     * (Thanks, libdbus.)
> +     *
> +     * The things that can set the unique name are:
> +     * - this function - but we don't release the GIL, so only one instance of
> +     *   this function can run
> +     * - dbus_bus_get - but this is only called in a __new__ or __new__-like
> +     *   function, so the new connection isn't available to other code yet
> +     *   and this function can't be called on it
> +     * - dbus_bus_register - same as dbus_bus_get
> +     *
> +     * Code outside dbus-python shouldn't be setting the unique name, because
> +     * we're using a private connection; we have to trust the authors
> +     * of mainloop bindings not to do silly things like that.
> +     */
> +    old_name = dbus_bus_get_unique_name(self->conn);
> +    if (old_name != NULL) {
> +        PyErr_Format(PyExc_ValueError, "This connection already has a "
> +                     "unique name: '%s'", old_name);
> +        return NULL;
> +    }
> +    dbus_bus_set_unique_name(self->conn, new_name);
> +
> +    Py_RETURN_NONE;
>  }
>  
>  /* vim:set ft=c cino< sw=4 sts=4 et: */
> diff --git a/_dbus_bindings/conn-internal.h b/_dbus_bindings/conn-internal.h
> index 8a542b4..9ca8f54 100644
> --- a/_dbus_bindings/conn-internal.h
> +++ b/_dbus_bindings/conn-internal.h
> @@ -50,4 +50,9 @@ extern PyObject *DBusPyConnection_ExistingFromDBusConnection(DBusConnection *);
>  extern PyObject *DBusPyConnection_GetObjectPathHandlers(PyObject *self,
>                                                          PyObject *path);
>  
> +extern PyObject *DBusPyConnection_NewForBus(PyTypeObject *cls, PyObject *args,
> +                                            PyObject *kwargs);
> +extern PyObject *DBusPyConnection_SetUniqueName(Connection *, PyObject *);
> +extern PyObject *DBusPyConnection_GetUniqueName(Connection *, PyObject *);
> +
>  #endif
> diff --git a/_dbus_bindings/conn-methods.c b/_dbus_bindings/conn-methods.c
> index 23ca1d3..6c1f90f 100644
> --- a/_dbus_bindings/conn-methods.c
> +++ b/_dbus_bindings/conn-methods.c
> @@ -914,6 +914,27 @@ Connection__unregister_object_path(Connection *self, PyObject *args,
>  
>  /* dbus_connection_get_outgoing_size - almost certainly unneeded */
>  
> +PyDoc_STRVAR(new_for_bus__doc__,
> +"Connection._new_for_bus([address: str or int]) -> Connection\n"
> +"\n"
> +"If the address is an int it must be one of the constants BUS_SESSION,\n"
> +"BUS_SYSTEM, BUS_STARTER; if a string, it must be a D-Bus address.\n"
> +"The default is BUS_SESSION.\n"
> +);
> +
> +PyDoc_STRVAR(get_unique_name__doc__,
> +"get_unique_name() -> str\n\n"
> +"Return this application's unique name on this bus.\n"
> +"\n"
> +":Raises DBusException: if the connection has no unique name yet\n"
> +"   (for Bus objects this can't happen, for peer-to-peer connections\n"
> +"   this means you haven't called `set_unique_name`)\n");
> +
> +PyDoc_STRVAR(set_unique_name__doc__,
> +"set_unique_name(str)\n\n"
> +"Set this application's unique name on this bus. Raise ValueError if it has\n"
> +"already been set.\n");
> +
>  struct PyMethodDef DBusPyConnection_tp_methods[] = {
>  #define ENTRY(name, flags) {#name, (PyCFunction)Connection_##name, flags, Connection_##name##__doc__}
>      ENTRY(_require_main_loop, METH_NOARGS),
> @@ -932,6 +953,15 @@ struct PyMethodDef DBusPyConnection_tp_methods[] = {
>      ENTRY(send_message_with_reply, METH_VARARGS|METH_KEYWORDS),
>      ENTRY(send_message_with_reply_and_block, METH_VARARGS),
>      ENTRY(_unregister_object_path, METH_VARARGS|METH_KEYWORDS),
> +    {"_new_for_bus", (PyCFunction)DBusPyConnection_NewForBus,
> +        METH_CLASS|METH_VARARGS|METH_KEYWORDS,
> +        new_for_bus__doc__},
> +    {"get_unique_name", (PyCFunction)DBusPyConnection_GetUniqueName,
> +        METH_NOARGS,
> +        get_unique_name__doc__},
> +    {"set_unique_name", (PyCFunction)DBusPyConnection_SetUniqueName,
> +        METH_VARARGS,
> +        set_unique_name__doc__},
>      {NULL},
>  #undef ENTRY
>  };
> diff --git a/_dbus_bindings/module.c b/_dbus_bindings/module.c
> index e21792d..cb74ac2 100644
> --- a/_dbus_bindings/module.c
> +++ b/_dbus_bindings/module.c
> @@ -266,7 +266,6 @@ init_dbus_bindings(void)
>      if (!dbus_py_init_pending_call()) return;
>      if (!dbus_py_init_mainloop()) return;
>      if (!dbus_py_init_conn_types()) return;
> -    if (!dbus_py_init_bus_types()) return;
>  
>      this_module = Py_InitModule3("_dbus_bindings", module_functions, module_doc);
>      if (!this_module) return;
> @@ -283,7 +282,6 @@ init_dbus_bindings(void)
>      if (!dbus_py_insert_pending_call(this_module)) return;
>      if (!dbus_py_insert_mainloop_types(this_module)) return;
>      if (!dbus_py_insert_conn_types(this_module)) return;
> -    if (!dbus_py_insert_bus_types(this_module)) return;
>  
>      if (PyModule_AddStringConstant(this_module, "BUS_DAEMON_NAME",
>                                     DBUS_SERVICE_DBUS) < 0) return;
> diff --git a/dbus/_dbus.py b/dbus/_dbus.py
> index 838b223..6812127 100644
> --- a/dbus/_dbus.py
> +++ b/dbus/_dbus.py
> @@ -29,7 +29,6 @@ __docformat__ = 'reStructuredText'
>  import _dbus_bindings
>  UTF8String = _dbus_bindings.UTF8String
>  DBusException = _dbus_bindings.DBusException
> -BusImplementation = _dbus_bindings.BusImplementation
>  
>  import os
>  import logging
> @@ -222,7 +221,7 @@ class SignalMatch(object):
>                                          **self._args_match)
>  
> 
> -class Bus(BusImplementation, _BusDaemonMixin):
> +class Bus(_dbus_bindings.Connection, _BusDaemonMixin):
>      """A connection to a DBus daemon.
>  
>      One of three possible standard buses, the SESSION, SYSTEM,
> @@ -288,8 +287,7 @@ class Bus(BusImplementation, _BusDaemonMixin):
>          else:
>              raise ValueError('invalid bus_type %s' % bus_type)
>  
> -        bus = _dbus_bindings.BusImplementation.__new__(subclass, bus_type,
> -                                                       mainloop=mainloop)
> +        bus = subclass._new_for_bus(bus_type, mainloop=mainloop)
>  
>          bus._bus_type = bus_type
>          # _bus_names is used by dbus.service.BusName!
> @@ -319,7 +317,7 @@ class Bus(BusImplementation, _BusDaemonMixin):
>          t = self._bus_type
>          if self.__class__._shared_instances[t] is self:
>              del self.__class__._shared_instances[t]
> -        BusImplementation.close(self)
> +        _dbus_bindings.Connection.close(self)
>  
>      def get_connection(self):
>          """(Deprecated - in new code, just use self)
> _______________________________________________
> dbus mailing list
> dbus at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dbus
-- 
John (J5) Palmieri <johnp at redhat.com>



More information about the dbus mailing list