[PATCH][python] Implement DBusException in pure Python; add get_dbus_name() method and name= keyword argument
Simon McVittie
simon.mcvittie at collabora.co.uk
Wed May 16 04:00:02 PDT 2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
- ---
_dbus_bindings/bus.c | 5 +-
_dbus_bindings/conn-methods.c | 6 +-
_dbus_bindings/dbus_bindings-internal.h | 2 +-
_dbus_bindings/exceptions.c | 99 ++++++++++++++++++-------------
_dbus_bindings/message.c | 6 +-
_dbus_bindings/module.c | 2 -
dbus/__init__.py | 7 +-
dbus/_dbus.py | 3 +-
dbus/bus.py | 2 +-
dbus/connection.py | 11 +--
dbus/dbus_bindings.py | 2 +-
dbus/decorators.py | 2 +
dbus/exceptions.py | 22 ++++++-
dbus/service.py | 11 ++-
14 files changed, 105 insertions(+), 75 deletions(-)
diff --git a/_dbus_bindings/bus.c b/_dbus_bindings/bus.c
index 1e3b81f..5d671ba 100644
- --- a/_dbus_bindings/bus.c
+++ b/_dbus_bindings/bus.c
@@ -103,9 +103,8 @@ DBusPyConnection_GetUniqueName(Connection *self, PyObject *args UNUSED)
name = dbus_bus_get_unique_name(self->conn);
Py_END_ALLOW_THREADS
if (!name) {
- - PyErr_SetString(DBusPyException, "This connection has no unique "
- - "name yet");
- - return NULL;
+ return DBusPyException_SetString("This connection has no unique name "
+ "yet");
}
return PyString_FromString(name);
}
diff --git a/_dbus_bindings/conn-methods.c b/_dbus_bindings/conn-methods.c
index 6c1f90f..1b41c46 100644
- --- a/_dbus_bindings/conn-methods.c
+++ b/_dbus_bindings/conn-methods.c
@@ -405,9 +405,8 @@ Connection_send_message_with_reply(Connection *self, PyObject *args, PyObject *k
if (!pending) {
/* connection is disconnected (doesn't return FALSE!) */
- - PyErr_SetString (DBusPyException, "Connection is disconnected - "
+ return DBusPyException_SetString ("Connection is disconnected - "
"unable to make method call");
- - return NULL;
}
return DBusPyPendingCall_ConsumeDBusPendingCall(pending, callable);
@@ -473,6 +472,9 @@ Connection_send_message_with_reply_and_block(Connection *self, PyObject *args)
timeout_ms, &error);
Py_END_ALLOW_THREADS
+ /* FIXME: if we instead used send_with_reply and blocked on the resulting
+ * PendingCall, then we could get all args from the error, not just
+ * the first */
if (!reply) {
return DBusPyException_ConsumeError(&error);
}
diff --git a/_dbus_bindings/dbus_bindings-internal.h b/_dbus_bindings/dbus_bindings-internal.h
index 392f58d..2e7f6ff 100644
- --- a/_dbus_bindings/dbus_bindings-internal.h
+++ b/_dbus_bindings/dbus_bindings-internal.h
@@ -65,7 +65,7 @@ extern dbus_bool_t dbus_py_init_bus_types(void);
extern dbus_bool_t dbus_py_insert_bus_types(PyObject *this_module);
/* exceptions.c */
- -extern PyObject *DBusPyException;
+extern PyObject *DBusPyException_SetString(const char *msg);
extern PyObject *DBusPyException_ConsumeError(DBusError *error);
extern dbus_bool_t dbus_py_init_exception_types(void);
extern dbus_bool_t dbus_py_insert_exception_types(PyObject *this_module);
diff --git a/_dbus_bindings/exceptions.c b/_dbus_bindings/exceptions.c
index 3578de1..c5554ba 100644
- --- a/_dbus_bindings/exceptions.c
+++ b/_dbus_bindings/exceptions.c
@@ -22,60 +22,75 @@
#include "dbus_bindings-internal.h"
- -PyObject *DBusPyException;
+static PyObject *imported_dbus_exception = NULL;
- -PyDoc_STRVAR(DBusException__doc__, "Represents any D-Bus-related error.");
+static dbus_bool_t
+import_exception(void)
+{
+ PyObject *name;
+ PyObject *exceptions;
+
+ if (imported_dbus_exception != NULL) {
+ return TRUE;
+ }
+
+ name = PyString_FromString("dbus.exceptions");
+ if (name == NULL) {
+ return FALSE;
+ }
+ exceptions = PyImport_Import(name);
+ Py_DECREF(name);
+ if (exceptions == NULL) {
+ return FALSE;
+ }
+ imported_dbus_exception = PyObject_GetAttrString(exceptions,
+ "DBusException");
+ Py_DECREF(exceptions);
+
+ return (imported_dbus_exception != NULL);
+}
PyObject *
- -DBusPyException_ConsumeError(DBusError *error)
+DBusPyException_SetString(const char *msg)
{
- - PyErr_Format(DBusPyException, "%s: %s",
- - error->name, error->message);
- - dbus_error_free(error);
+ if (imported_dbus_exception != NULL || import_exception()) {
+ PyErr_SetString(imported_dbus_exception, msg);
+ }
return NULL;
}
- -dbus_bool_t
- -dbus_py_init_exception_types(void)
+PyObject *
+DBusPyException_ConsumeError(DBusError *error)
{
- - PyObject *bases;
- - PyObject *dict = PyDict_New();
- - PyObject *name;
+ PyObject *exc_value = NULL;
- - if (!dict)
- - return 0;
- - if (PyDict_SetItemString(dict, "__doc__",
- - PyString_FromString(DBusException__doc__)) < 0)
- - return 0;
- - if (PyDict_SetItemString(dict, "__module__",
- - PyString_FromString("dbus")) < 0)
- - return 0;
- - bases = Py_BuildValue("(O)", (PyObject *)PyExc_Exception);
- - if (!bases) {
- - Py_DECREF(dict);
- - return 0;
+ if (imported_dbus_exception == NULL && !import_exception()) {
+ goto finally;
}
- - name = PyString_FromString("DBusException");
- - if (!name) {
- - Py_DECREF(dict);
- - Py_DECREF(bases);
- - return 0;
- - }
- - DBusPyException = PyClass_New(bases, dict, name);
- - Py_DECREF(bases);
- - Py_DECREF(dict);
- - if (!DBusPyException)
- - return 0;
- - return 1;
- -}
- -dbus_bool_t
- -dbus_py_insert_exception_types(PyObject *this_module)
- -{
- - if (PyModule_AddObject(this_module, "DBusException", DBusPyException) < 0) {
- - return 0;
+ exc_value = PyObject_CallFunction(imported_dbus_exception,
+ "s",
+ error->message ? error->message
+ : "");
+ if (error->name) {
+ PyObject *name = PyString_FromString(error->name);
+ int ret;
+
+ if (!name)
+ goto finally;
+ ret = PyObject_SetAttrString(exc_value, "_dbus_error_name", name);
+ Py_DECREF(name);
+ if (ret < 0) {
+ goto finally;
+ }
}
- - return 1;
+
+ PyErr_SetObject(imported_dbus_exception, exc_value);
+
+finally:
+ Py_XDECREF(exc_value);
+ dbus_error_free(error);
+ return NULL;
}
/* vim:set ft=c cino< sw=4 sts=4 et: */
diff --git a/_dbus_bindings/message.c b/_dbus_bindings/message.c
index 436690e..3887aaa 100644
- --- a/_dbus_bindings/message.c
+++ b/_dbus_bindings/message.c
@@ -36,9 +36,9 @@ static inline int Message_Check(PyObject *o)
PyObject *
DBusPy_RaiseUnusableMessage(void)
{
- - PyErr_SetString(DBusPyException,
- - "Message object is uninitialized, or has become unusable "
- - "due to error while appending arguments");
+ DBusPyException_SetString("Message object is uninitialized, or has become "
+ "unusable due to error while appending "
+ "arguments");
return NULL;
}
diff --git a/_dbus_bindings/module.c b/_dbus_bindings/module.c
index cb74ac2..a0e5c95 100644
- --- a/_dbus_bindings/module.c
+++ b/_dbus_bindings/module.c
@@ -254,7 +254,6 @@ init_dbus_bindings(void)
}
if (!dbus_py_init_generic()) return;
- - if (!dbus_py_init_exception_types()) return;
if (!dbus_py_init_abstract()) return;
if (!dbus_py_init_signature()) return;
if (!dbus_py_init_int_types()) return;
@@ -270,7 +269,6 @@ init_dbus_bindings(void)
this_module = Py_InitModule3("_dbus_bindings", module_functions, module_doc);
if (!this_module) return;
- - if (!dbus_py_insert_exception_types(this_module)) return;
if (!dbus_py_insert_abstract_types(this_module)) return;
if (!dbus_py_insert_signature(this_module)) return;
if (!dbus_py_insert_int_types(this_module)) return;
diff --git a/dbus/__init__.py b/dbus/__init__.py
index efd9aa6..9ad884b 100644
- --- a/dbus/__init__.py
+++ b/dbus/__init__.py
@@ -50,13 +50,12 @@ __all__ = (
'LOCAL_PATH', 'LOCAL_IFACE', 'PEER_IFACE',
'INTROSPECTABLE_IFACE', 'PROPERTIES_IFACE',
- - 'DBusException',
- -
'ObjectPath', 'ByteArray', 'Signature', 'Byte', 'Boolean',
'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64',
'Double', 'String', 'Array', 'Struct', 'Dictionary', 'UTF8String',
# from exceptions
+ 'DBusException',
'MissingErrorHandlerException', 'MissingReplyHandlerException',
'ValidationException', 'IntrospectionParserException',
'UnknownMethodException', 'NameExistsException',
@@ -82,14 +81,14 @@ from _dbus_bindings import get_default_main_loop, set_default_main_loop,\
from _dbus_bindings import BUS_DAEMON_NAME, BUS_DAEMON_PATH, BUS_DAEMON_IFACE,\
LOCAL_PATH, LOCAL_IFACE, PEER_IFACE,\
INTROSPECTABLE_IFACE, PROPERTIES_IFACE
- -from _dbus_bindings import DBusException
from dbus.exceptions import MissingErrorHandlerException, \
MissingReplyHandlerException, \
ValidationException, \
IntrospectionParserException, \
UnknownMethodException, \
- - NameExistsException
+ NameExistsException, \
+ DBusException
from _dbus_bindings import ObjectPath, ByteArray, Signature, Byte, Boolean,\
Int16, UInt16, Int32, UInt32, Int64, UInt64,\
Double, String, Array, Struct, Dictionary, \
diff --git a/dbus/_dbus.py b/dbus/_dbus.py
index d46aa9b..3b96201 100644
- --- a/dbus/_dbus.py
+++ b/dbus/_dbus.py
@@ -31,8 +31,9 @@ import sys
import weakref
from traceback import print_exc
+from dbus.exceptions import DBusException
from _dbus_bindings import BUS_DAEMON_NAME, BUS_DAEMON_PATH,\
- - BUS_DAEMON_IFACE, DBusException, UTF8String,\
+ BUS_DAEMON_IFACE, UTF8String,\
validate_member_name, validate_interface_name,\
validate_bus_name, validate_object_path,\
BUS_SESSION, BUS_SYSTEM, BUS_STARTER,\
diff --git a/dbus/bus.py b/dbus/bus.py
index 80118aa..645f6a8 100644
- --- a/dbus/bus.py
+++ b/dbus/bus.py
@@ -25,13 +25,13 @@ import weakref
from _dbus_bindings import validate_interface_name, validate_member_name,\
validate_bus_name, validate_object_path,\
validate_error_name,\
- - DBusException, \
BUS_SESSION, BUS_STARTER, BUS_SYSTEM, \
DBUS_START_REPLY_SUCCESS, \
DBUS_START_REPLY_ALREADY_RUNNING, \
BUS_DAEMON_NAME, BUS_DAEMON_PATH, BUS_DAEMON_IFACE,\
HANDLER_RESULT_NOT_YET_HANDLED
from dbus.connection import Connection
+from dbus.exceptions import DBusException
_NAME_OWNER_CHANGE_MATCH = ("type='signal',sender='%s',"
diff --git a/dbus/connection.py b/dbus/connection.py
index fd0fe7a..1304058 100644
- --- a/dbus/connection.py
+++ b/dbus/connection.py
@@ -28,12 +28,13 @@ import weakref
from _dbus_bindings import Connection as _Connection, ErrorMessage, \
MethodCallMessage, MethodReturnMessage, \
- - DBusException, LOCAL_PATH, LOCAL_IFACE, \
+ LOCAL_PATH, LOCAL_IFACE, \
validate_interface_name, validate_member_name,\
validate_bus_name, validate_object_path,\
validate_error_name, \
HANDLER_RESULT_NOT_YET_HANDLED, \
UTF8String, SignalMessage
+from dbus.exceptions import DBusException
from dbus.proxies import ProxyObject
@@ -548,12 +549,8 @@ class Connection(_Connection):
if isinstance(message, MethodReturnMessage):
reply_handler(*message.get_args_list(**get_args_opts))
elif isinstance(message, ErrorMessage):
- - args = message.get_args_list()
- - # FIXME: should we do something with the rest?
- - if len(args) > 0:
- - error_handler(DBusException(args[0]))
- - else:
- - error_handler(DBusException())
+ error_handler(DBusException(name=message.get_error_name(),
+ *message.get_args_list()))
else:
error_handler(TypeError('Unexpected type for reply '
'message: %r' % message))
diff --git a/dbus/dbus_bindings.py b/dbus/dbus_bindings.py
index 050a4e1..a45ca9f 100644
- --- a/dbus/dbus_bindings.py
+++ b/dbus/dbus_bindings.py
@@ -16,7 +16,7 @@ If you need additional public API, please contact the maintainers via
_warn(_dbus_bindings_warning, DeprecationWarning, stacklevel=2)
# Exceptions
- -from _dbus_bindings import DBusException
+from dbus.exceptions import DBusException
class ConnectionError(Exception): pass
# Types
diff --git a/dbus/decorators.py b/dbus/decorators.py
index aa08940..9cc0dbe 100644
- --- a/dbus/decorators.py
+++ b/dbus/decorators.py
@@ -28,6 +28,8 @@ import inspect
import _dbus_bindings
+from dbus.exceptions import DBusException
+
def method(dbus_interface, in_signature=None, out_signature=None,
async_callbacks=None,
diff --git a/dbus/exceptions.py b/dbus/exceptions.py
index 801ede6..545d62f 100644
- --- a/dbus/exceptions.py
+++ b/dbus/exceptions.py
@@ -5,9 +5,23 @@ __all__ = ('DBusException', 'MissingErrorHandlerException',
'IntrospectionParserException', 'UnknownMethodException',
'NameExistsException')
- -import _dbus_bindings
- -
- -DBusException = _dbus_bindings.DBusException
+class DBusException(Exception):
+ def __init__(self, *args, **kwargs):
+ self._dbus_error_name = kwargs.pop('name', None)
+ if kwargs:
+ raise TypeError('DBusException does not take keyword arguments: %s'
+ % ', '.join(kwargs.keys()))
+ Exception.__init__(self, *args)
+
+ def __str__(self):
+ s = Exception.__str__(self)
+ if self._dbus_error_name is not None:
+ return '%s: %s' % (self._dbus_error_name, s)
+ else:
+ return s
+
+ def get_dbus_name(self):
+ return self._dbus_error_name
class MissingErrorHandlerException(DBusException):
def __init__(self):
@@ -26,10 +40,10 @@ class IntrospectionParserException(DBusException):
DBusException.__init__(self, "Error parsing introspect data: %s"%msg)
class UnknownMethodException(DBusException):
+ _dbus_error_name = 'org.freedesktop.DBus.Error.UnknownMethod'
def __init__(self, method):
DBusException.__init__(self, "Unknown method: %s"%method)
class NameExistsException(DBusException):
def __init__(self, name):
DBusException.__init__(self, "Bus name already exists: %s"%name)
- -
diff --git a/dbus/service.py b/dbus/service.py
index 9b4c262..9d3dc3f 100644
- --- a/dbus/service.py
+++ b/dbus/service.py
@@ -29,8 +29,9 @@ import traceback
import _dbus_bindings
from dbus import SessionBus
- -from dbus.exceptions import NameExistsException
- -from dbus.exceptions import UnknownMethodException
+from dbus.exceptions import DBusException, \
+ NameExistsException, \
+ UnknownMethodException
from dbus.decorators import method
from dbus.decorators import signal
from dbus.proxies import LOCAL_PATH
@@ -249,8 +250,10 @@ def _method_reply_return(connection, message, method_name, signature, *retval):
def _method_reply_error(connection, message, exception):
- - if hasattr(exception, '_dbus_error_name'):
- - name = exception._dbus_error_name
+ name = getattr(exception, '_dbus_error_name', None)
+
+ if name is not None:
+ pass
elif getattr(exception, '__module__', '') in ('', '__main__'):
name = 'org.freedesktop.DBus.Python.%s' % exception.__class__.__name__
else:
- --
1.5.2-rc2.GIT
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: OpenPGP key: http://www.pseudorandom.co.uk/2003/contact/ or pgp.net
iD8DBQFGSuQxWSc8zVUw7HYRApPvAJ4vi1v/IR0nd/opAYAugiH/FlGnxQCgsJ6Q
/lKdRaguMRWbt0zm94xo8Po=
=NT/3
-----END PGP SIGNATURE-----
More information about the dbus
mailing list