[PATCH][python] Implement DBusException in pure Python; add get_dbus_name() method and name= keyword argument
John (J5) Palmieri
johnp at redhat.com
Fri May 18 08:54:28 PDT 2007
Looks good
On Wed, 2007-05-16 at 12:00 +0100, Simon McVittie wrote:
> -----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-----
> _______________________________________________
> dbus mailing list
> dbus at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dbus
More information about the dbus
mailing list