From 3aff827e8fe14a9fb9b1846e00c32f01afee40b2 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 30 Nov 2006 11:03:19 +0000 Subject: [PATCH] _dbus_bindings: Change default-main-loop API to use global functions get_default_main_loop, set_default_main_loop. Improve docstrings --- _dbus_bindings/bus-impl.h | 5 +-- _dbus_bindings/conn-impl.h | 32 +++++++---------- _dbus_bindings/conn-methods-impl.h | 56 ------------------------------ _dbus_bindings/mainloop-impl.h | 70 ++++++++++++++++++++++++++++++++++++-- _dbus_bindings/module.c | 12 ++++--- 5 files changed, 91 insertions(+), 84 deletions(-) diff --git a/_dbus_bindings/bus-impl.h b/_dbus_bindings/bus-impl.h index c5db0c8..6581a89 100644 --- a/_dbus_bindings/bus-impl.h +++ b/_dbus_bindings/bus-impl.h @@ -23,7 +23,7 @@ */ PyDoc_STRVAR(Bus_tp_doc, -"Bus([address: str or int])\n\n" +"BusImplementation([address: str or int])\n\n" "If the address is an int it must be one of the constants BUS_SESSION,\n" "BUS_SYSTEM, BUS_STARTER. The default is BUS_SESSION.\n" ); @@ -381,7 +381,7 @@ static PyTypeObject BusType = { Bus_tp_methods, /*tp_methods*/ 0, /*tp_members*/ 0, /*tp_getset*/ - &ConnectionType, /*tp_base*/ + DEFERRED_ADDRESS(&ConnectionType), /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ @@ -396,6 +396,7 @@ static PyTypeObject BusType = { static inline int init_bus_types (void) { + BusType.tp_base = &ConnectionType; if (PyType_Ready (&BusType) < 0) return 0; return 1; } diff --git a/_dbus_bindings/conn-impl.h b/_dbus_bindings/conn-impl.h index 97c99c1..3c87e4e 100644 --- a/_dbus_bindings/conn-impl.h +++ b/_dbus_bindings/conn-impl.h @@ -26,7 +26,8 @@ /* Connection definition ============================================ */ PyDoc_STRVAR(Connection_tp_doc, -"Connection(address: str)\n\n" +"A D-Bus connection.\n\n" +"Connection(address: str, mainloop=None) -> Connection\n" ); typedef struct Connection { @@ -235,9 +236,6 @@ out: */ static dbus_int32_t _connection_python_slot; -/* The main loop if none is passed to the constructor */ -static PyObject *Connection_default_main_loop; - /* C API for main-loop hooks ======================================== */ /* Return a borrowed reference to the DBusConnection which underlies this @@ -348,10 +346,6 @@ Connection_ExistingFromDBusConnection(DBusConnection *conn) return NULL; } -static dbus_bool_t dbus_python_set_up_connection(Connection *conn, - PyObject *mainloop); -static dbus_bool_t check_mainloop_sanity(PyObject *mainloop); - /* Return a new reference to a Python Connection or subclass (given by cls) * corresponding to the DBusConnection conn, which must have been newly * created. For use by the Connection and Bus constructors. @@ -385,7 +379,7 @@ Connection_NewConsumingDBusConnection(PyTypeObject *cls, ref = NULL; if (!mainloop || mainloop == Py_None) { - mainloop = Connection_default_main_loop; + mainloop = default_main_loop; if (!mainloop || mainloop == Py_None) { PyErr_SetString(PyExc_ValueError, "D-Bus connections must be attached to a main " @@ -425,7 +419,7 @@ Connection_NewConsumingDBusConnection(PyTypeObject *cls, self->conn = conn; - if (!dbus_python_set_up_connection(self, mainloop)) { + if (!dbus_python_set_up_connection((PyObject *)self, mainloop)) { goto err; } @@ -556,25 +550,23 @@ static PyTypeObject ConnectionType = { static inline dbus_bool_t init_conn_types(void) { - Connection_default_main_loop = NULL; + default_main_loop = NULL; /* Get a slot to store our weakref on DBus Connections */ _connection_python_slot = -1; - if (!dbus_connection_allocate_data_slot(&_connection_python_slot)) { - return 0; - } - - ConnectionType.tp_new = PyType_GenericNew; - if (PyType_Ready(&ConnectionType) < 0) return 0; - return 1; + if (!dbus_connection_allocate_data_slot(&_connection_python_slot)) + return FALSE; + if (PyType_Ready(&ConnectionType) < 0) + return FALSE; + return TRUE; } static inline dbus_bool_t insert_conn_types(PyObject *this_module) { if (PyModule_AddObject(this_module, "Connection", - (PyObject *)&ConnectionType) < 0) return 0; - return 1; + (PyObject *)&ConnectionType) < 0) return FALSE; + return TRUE; } /* vim:set ft=c cino< sw=4 sts=4 et: */ diff --git a/_dbus_bindings/conn-methods-impl.h b/_dbus_bindings/conn-methods-impl.h index 7ca387b..0806841 100644 --- a/_dbus_bindings/conn-methods-impl.h +++ b/_dbus_bindings/conn-methods-impl.h @@ -650,60 +650,6 @@ Connection__unregister_object_path(Connection *self, PyObject *args, /* dbus_connection_get_outgoing_size - almost certainly unneeded */ -PyDoc_STRVAR(Connection_get_default_main_loop__doc__, -"Connection.get_default_main_loop() -> object\n\n" -"Return the global default dbus-python main loop wrapper, which is used\n" -"when no main loop wrapper is passed to the Connection constructor.\n" -"\n" -"If None, there is no default and you must always pass the mainloop\n" -"parameter to the constructor. This will be the case until\n" -"set_default_main_loop is called.\n"); -static PyObject * -Connection_get_default_main_loop(PyObject *always_null UNUSED, - PyObject *no_args UNUSED) -{ - if (!Connection_default_main_loop) { - Py_RETURN_NONE; - } - Py_INCREF(Connection_default_main_loop); - return Connection_default_main_loop; -} - -PyDoc_STRVAR(Connection_set_default_main_loop__doc__, -"Connection.set_default_main_loop(object)\n\n" -"Change the global default dbus-python main loop wrapper, which is used\n" -"when no main loop wrapper is passed to the Connection constructor.\n" -"\n" -"If None, return to the initial situation: there is no default, and you\n" -"must always pass the mainloop parameter to the constructor.\n" -"\n" -"There are two types of main loop wrapper in dbus-python. Python\n" -"main-loop wrappers are objects supporting the interface defined by\n" -"`dbus.mainloop.MainLoop`; their API is entirely based on Python\n" -"methods.\n" -"\n" -"Native main-loop wrappers are instances of dbus.mainloop.NativeMainLoop\n" -"supplied by extension modules like `dbus.mainloop.glib`: they have no\n" -"Python API, but connect themselves to ``libdbus`` using native code.\n"); -static PyObject * -Connection_set_default_main_loop(PyObject *always_null UNUSED, - PyObject *args) -{ - PyObject *new_loop, *old_loop; - - if (!PyArg_ParseTuple(args, "O", &new_loop)) { - return NULL; - } - if (!check_mainloop_sanity(new_loop)) { - return NULL; - } - old_loop = Connection_default_main_loop; - Py_INCREF(new_loop); - Connection_default_main_loop = new_loop; - Py_XDECREF(old_loop); - Py_RETURN_NONE; -} - static struct PyMethodDef Connection_tp_methods[] = { #define ENTRY(name, flags) {#name, (PyCFunction)Connection_##name, flags, Connection_##name##__doc__} ENTRY(close, METH_NOARGS), @@ -721,8 +667,6 @@ static struct PyMethodDef Connection_tp_methods[] = { ENTRY(_send_with_reply, METH_VARARGS), ENTRY(_send_with_reply_and_block, METH_VARARGS), ENTRY(_unregister_object_path, METH_VARARGS|METH_KEYWORDS), - ENTRY(get_default_main_loop, METH_NOARGS|METH_STATIC), - ENTRY(set_default_main_loop, METH_VARARGS|METH_STATIC), {NULL}, #undef ENTRY }; diff --git a/_dbus_bindings/mainloop-impl.h b/_dbus_bindings/mainloop-impl.h index 4634142..21dbacf 100644 --- a/_dbus_bindings/mainloop-impl.h +++ b/_dbus_bindings/mainloop-impl.h @@ -437,6 +437,8 @@ static PyTypeObject NativeMainLoopType = { 0, /* tp_new */ }; +/* Internal C API for Connection, Bus, Server ======================= */ + static dbus_bool_t check_mainloop_sanity(PyObject *mainloop) { @@ -449,18 +451,82 @@ check_mainloop_sanity(PyObject *mainloop) } static dbus_bool_t -dbus_python_set_up_connection(Connection *conn, PyObject *mainloop) +dbus_python_set_up_connection(PyObject *conn, PyObject *mainloop) { if (NativeMainLoop_Check(mainloop)) { /* Native mainloops are allowed to do arbitrary strange things */ NativeMainLoop *nml = (NativeMainLoop *)mainloop; - return (nml->set_up_connection_cb)(conn->conn, nml->data); + DBusConnection *dbc = Connection_BorrowDBusConnection(conn); + + if (!dbc) { + return FALSE; + } + return (nml->set_up_connection_cb)(dbc, nml->data); } PyErr_SetString(PyExc_TypeError, "A dbus.mainloop.NativeMainLoop instance is required"); return FALSE; } +/* The main loop if none is passed to the constructor */ +static PyObject *default_main_loop; + +/* Python API ======================================================= */ + +PyDoc_STRVAR(get_default_main_loop__doc__, +"get_default_main_loop() -> object\n\n" +"Return the global default dbus-python main loop wrapper, which is used\n" +"when no main loop wrapper is passed to the Connection constructor.\n" +"\n" +"If None, there is no default and you must always pass the mainloop\n" +"parameter to the constructor. This will be the case until\n" +"set_default_main_loop is called.\n"); +static PyObject * +get_default_main_loop(PyObject *always_null UNUSED, + PyObject *no_args UNUSED) +{ + if (!default_main_loop) { + Py_RETURN_NONE; + } + Py_INCREF(default_main_loop); + return default_main_loop; +} + +PyDoc_STRVAR(set_default_main_loop__doc__, +"set_default_main_loop(object)\n\n" +"Change the global default dbus-python main loop wrapper, which is used\n" +"when no main loop wrapper is passed to the Connection constructor.\n" +"\n" +"If None, return to the initial situation: there is no default, and you\n" +"must always pass the mainloop parameter to the constructor.\n" +"\n" +"There are two types of main loop wrapper in dbus-python. Python\n" +"main-loop wrappers are objects supporting the interface defined by\n" +"`dbus.mainloop.MainLoop`; their API is entirely based on Python\n" +"methods.\n" +"\n" +"Native main-loop wrappers are instances of dbus.mainloop.NativeMainLoop\n" +"supplied by extension modules like `dbus.mainloop.glib`: they have no\n" +"Python API, but connect themselves to ``libdbus`` using native code.\n"); +static PyObject * +set_default_main_loop(PyObject *always_null UNUSED, + PyObject *args) +{ + PyObject *new_loop, *old_loop; + + if (!PyArg_ParseTuple(args, "O", &new_loop)) { + return NULL; + } + if (!check_mainloop_sanity(new_loop)) { + return NULL; + } + old_loop = default_main_loop; + Py_INCREF(new_loop); + default_main_loop = new_loop; + Py_XDECREF(old_loop); + Py_RETURN_NONE; +} + /* C API ============================================================ */ static PyObject * diff --git a/_dbus_bindings/module.c b/_dbus_bindings/module.c index c66af7d..98be546 100644 --- a/_dbus_bindings/module.c +++ b/_dbus_bindings/module.c @@ -29,7 +29,9 @@ #include "dbus_bindings.h" PyDoc_STRVAR(module_doc, -"Low-level Python bindings for libdbus.\n"); +"Low-level Python bindings for libdbus. Don't use this module directly -\n" +"the public API is provided by the `dbus`, `dbus.service`, `dbus.mainloop`\n" +"and `dbus.mainloop.glib` modules.\n"); #include "debug-impl.h" /* DBG, USING_DBG, DBG_EXC */ #include "generic-impl.h" /* Non D-Bus support code */ @@ -43,9 +45,9 @@ PyDoc_STRVAR(module_doc, #include "bytes-impl.h" /* Byte, ByteArray */ #include "message-impl.h" /* Message and subclasses */ #include "pending-call-impl.h" /* PendingCall */ +#include "mainloop-impl.h" /* NativeMainLoop */ #include "conn-impl.h" /* Connection */ #include "bus-impl.h" /* Bus */ -#include "mainloop-impl.h" /* NativeMainLoop */ static PyMethodDef module_functions[] = { #define ENTRY(name,flags) {#name, (PyCFunction)name, flags, name##__doc__} @@ -53,6 +55,8 @@ static PyMethodDef module_functions[] = { ENTRY(validate_member_name, METH_VARARGS), ENTRY(validate_bus_name, METH_VARARGS|METH_KEYWORDS), ENTRY(validate_object_path, METH_VARARGS), + ENTRY(set_default_main_loop, METH_VARARGS), + ENTRY(get_default_main_loop, METH_NOARGS), /* validate_error_name is just implemented as validate_interface_name */ {"validate_error_name", validate_interface_name, METH_VARARGS, validate_error_name__doc__}, @@ -81,9 +85,9 @@ init_dbus_bindings(void) if (!init_byte_types()) return; if (!init_message_types()) return; if (!init_pending_call()) return; + if (!init_mainloop()) return; if (!init_conn_types()) return; if (!init_bus_types()) return; - if (!init_mainloop()) return; this_module = Py_InitModule3("_dbus_bindings", module_functions, module_doc); if (!this_module) return; @@ -97,9 +101,9 @@ init_dbus_bindings(void) if (!insert_byte_types(this_module)) return; if (!insert_message_types(this_module)) return; if (!insert_pending_call(this_module)) return; + if (!insert_mainloop_types(this_module)) return; if (!insert_conn_types(this_module)) return; if (!insert_bus_types(this_module)) return; - if (!insert_mainloop_types(this_module)) return; #define ADD_CONST_VAL(x, v) \ if (PyModule_AddIntConstant(this_module, x, v) < 0) return; -- 2.11.4.GIT