summaryrefslogtreecommitdiff
path: root/_dbus_bindings/message-append.c
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2011-12-15 06:57:21 -0500
committerBarry Warsaw <barry@python.org>2011-12-15 06:57:21 -0500
commit4c1c2eade1c5b383adad94a7a4fd6553873fecf0 (patch)
treeb9e0f45fc19539bcaddff69e661bf0c5d21bab5a /_dbus_bindings/message-append.c
parent667082d0b4aef9c438a2e7fec89614b5b8ef960a (diff)
This is the big one; it adds Python 3 support.
Diffstat (limited to '_dbus_bindings/message-append.c')
-rw-r--r--_dbus_bindings/message-append.c195
1 files changed, 158 insertions, 37 deletions
diff --git a/_dbus_bindings/message-append.c b/_dbus_bindings/message-append.c
index 4298b3b..c08f498 100644
--- a/_dbus_bindings/message-append.c
+++ b/_dbus_bindings/message-append.c
@@ -38,9 +38,14 @@
static long
get_variant_level(PyObject *obj)
{
- if (DBusPyIntBase_Check(obj)) {
+ if (DBusPyString_Check(obj)) {
+ return ((DBusPyString *)obj)->variant_level;
+ }
+#ifndef PY3
+ else if (DBusPyIntBase_Check(obj)) {
return ((DBusPyIntBase *)obj)->variant_level;
}
+#endif
else if (DBusPyFloatBase_Check(obj)) {
return ((DBusPyFloatBase *)obj)->variant_level;
}
@@ -50,10 +55,10 @@ get_variant_level(PyObject *obj)
else if (DBusPyDict_Check(obj)) {
return ((DBusPyDict *)obj)->variant_level;
}
- else if (DBusPyString_Check(obj)) {
- return ((DBusPyString *)obj)->variant_level;
- }
else if (DBusPyLongBase_Check(obj) ||
+#ifdef PY3
+ DBusPyBytesBase_Check(obj) ||
+#endif
DBusPyStrBase_Check(obj) ||
DBusPyStruct_Check(obj)) {
return dbus_py_variant_level_get(obj);
@@ -143,7 +148,7 @@ get_object_path(PyObject *obj)
PyObject *magic_attr = PyObject_GetAttr(obj, dbus_py__dbus_object_path__const);
if (magic_attr) {
- if (PyBytes_Check(magic_attr)) {
+ if (PyUnicode_Check(magic_attr) || PyBytes_Check(magic_attr)) {
return magic_attr;
}
else {
@@ -179,11 +184,11 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr)
*variant_level_ptr = variant_level;
}
else if (variant_level > 0) {
- return PyBytes_FromString(DBUS_TYPE_VARIANT_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_VARIANT_AS_STRING);
}
if (obj == Py_True || obj == Py_False) {
- return PyBytes_FromString(DBUS_TYPE_BOOLEAN_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_BOOLEAN_AS_STRING);
}
magic_attr = get_object_path(obj);
@@ -191,61 +196,84 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr)
return NULL;
if (magic_attr != Py_None) {
Py_CLEAR(magic_attr);
- return PyBytes_FromString(DBUS_TYPE_OBJECT_PATH_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_OBJECT_PATH_AS_STRING);
}
Py_CLEAR(magic_attr);
/* Ordering is important: some of these are subclasses of each other. */
+#ifdef PY3
+ if (PyLong_Check(obj)) {
+ if (DBusPyUInt64_Check(obj))
+ return NATIVESTR_FROMSTR(DBUS_TYPE_UINT64_AS_STRING);
+ else if (DBusPyInt64_Check(obj))
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT64_AS_STRING);
+ else if (DBusPyUInt32_Check(obj))
+ return NATIVESTR_FROMSTR(DBUS_TYPE_UINT32_AS_STRING);
+ else if (DBusPyInt32_Check(obj))
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT32_AS_STRING);
+ else if (DBusPyUInt16_Check(obj))
+ return NATIVESTR_FROMSTR(DBUS_TYPE_UINT16_AS_STRING);
+ else if (DBusPyInt16_Check(obj))
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT16_AS_STRING);
+ else if (DBusPyByte_Check(obj))
+ return NATIVESTR_FROMSTR(DBUS_TYPE_BYTE_AS_STRING);
+ else if (DBusPyBoolean_Check(obj))
+ return NATIVESTR_FROMSTR(DBUS_TYPE_BOOLEAN_AS_STRING);
+ else
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT32_AS_STRING);
+ }
+#else /* !PY3 */
if (PyInt_Check(obj)) {
if (DBusPyInt16_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_INT16_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT16_AS_STRING);
else if (DBusPyInt32_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_INT32_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT32_AS_STRING);
else if (DBusPyByte_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_BYTE_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_BYTE_AS_STRING);
else if (DBusPyUInt16_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_UINT16_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_UINT16_AS_STRING);
else if (DBusPyBoolean_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_BOOLEAN_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_BOOLEAN_AS_STRING);
else
- return PyBytes_FromString(DBUS_TYPE_INT32_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT32_AS_STRING);
}
else if (PyLong_Check(obj)) {
if (DBusPyInt64_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_INT64_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT64_AS_STRING);
else if (DBusPyUInt32_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_UINT32_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_UINT32_AS_STRING);
else if (DBusPyUInt64_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_UINT64_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_UINT64_AS_STRING);
else
- return PyBytes_FromString(DBUS_TYPE_INT64_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_INT64_AS_STRING);
}
+#endif /* PY3 */
else if (PyUnicode_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_STRING_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_STRING_AS_STRING);
#if defined(DBUS_TYPE_UNIX_FD)
else if (DBusPyUnixFd_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_UNIX_FD_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_UNIX_FD_AS_STRING);
#endif
else if (PyFloat_Check(obj)) {
#ifdef WITH_DBUS_FLOAT32
if (DBusPyDouble_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_DOUBLE_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_DOUBLE_AS_STRING);
else if (DBusPyFloat_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_FLOAT_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_FLOAT_AS_STRING);
else
#endif
- return PyBytes_FromString(DBUS_TYPE_DOUBLE_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_DOUBLE_AS_STRING);
}
else if (PyBytes_Check(obj)) {
if (DBusPyObjectPath_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_OBJECT_PATH_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_OBJECT_PATH_AS_STRING);
else if (DBusPySignature_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_SIGNATURE_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_SIGNATURE_AS_STRING);
else if (DBusPyByteArray_Check(obj))
- return PyBytes_FromString(DBUS_TYPE_ARRAY_AS_STRING
- DBUS_TYPE_BYTE_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_TYPE_BYTE_AS_STRING);
else
- return PyBytes_FromString(DBUS_TYPE_STRING_AS_STRING);
+ return NATIVESTR_FROMSTR(DBUS_TYPE_STRING_AS_STRING);
}
else if (PyTuple_Check(obj)) {
Py_ssize_t len = PyTuple_GET_SIZE(obj);
@@ -262,12 +290,12 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr)
return NULL;
}
/* Set the first and last elements of list to be the parentheses */
- item = PyBytes_FromString(DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
+ item = NATIVESTR_FROMSTR(DBUS_STRUCT_BEGIN_CHAR_AS_STRING);
if (PyList_SetItem(list, 0, item) < 0) {
Py_CLEAR(list);
return NULL;
}
- item = PyBytes_FromString(DBUS_STRUCT_END_CHAR_AS_STRING);
+ item = NATIVESTR_FROMSTR(DBUS_STRUCT_END_CHAR_AS_STRING);
if (PyList_SetItem(list, len + 1, item) < 0) {
Py_CLEAR(list);
return NULL;
@@ -295,7 +323,7 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr)
}
item = NULL;
}
- empty_str = PyBytes_FromString("");
+ empty_str = NATIVESTR_FROMSTR("");
if (!empty_str) {
/* really shouldn't happen */
Py_CLEAR(list);
@@ -309,14 +337,25 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr)
}
else if (PyList_Check(obj)) {
PyObject *tmp;
- PyObject *ret = PyBytes_FromString(DBUS_TYPE_ARRAY_AS_STRING);
+ PyObject *ret = NATIVESTR_FROMSTR(DBUS_TYPE_ARRAY_AS_STRING);
if (!ret) return NULL;
+#ifdef PY3
+ if (DBusPyArray_Check(obj) &&
+ PyUnicode_Check(((DBusPyArray *)obj)->signature))
+ {
+ PyObject *concat = PyUnicode_Concat(
+ ret, ((DBusPyArray *)obj)->signature);
+ Py_CLEAR(ret);
+ return concat;
+ }
+#else
if (DBusPyArray_Check(obj) &&
PyBytes_Check(((DBusPyArray *)obj)->signature))
{
PyBytes_Concat(&ret, ((DBusPyArray *)obj)->signature);
return ret;
}
+#endif
if (PyList_GET_SIZE(obj) == 0) {
/* No items, so fail. Or should we guess "av"? */
PyErr_SetString(PyExc_ValueError, "Unable to guess signature "
@@ -326,14 +365,34 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr)
tmp = PyList_GetItem(obj, 0);
tmp = _signature_string_from_pyobject(tmp, NULL);
if (!tmp) return NULL;
+#ifdef PY3
+ {
+ PyObject *concat = PyUnicode_Concat(ret, tmp);
+ Py_CLEAR(ret);
+ Py_CLEAR(tmp);
+ return concat;
+ }
+#else
PyBytes_ConcatAndDel(&ret, tmp);
return ret;
+#endif
}
else if (PyDict_Check(obj)) {
PyObject *key, *value, *keysig, *valuesig;
Py_ssize_t pos = 0;
PyObject *ret = NULL;
+#ifdef PY3
+ if (DBusPyDict_Check(obj) &&
+ PyUnicode_Check(((DBusPyDict *)obj)->signature))
+ {
+ return PyUnicode_FromFormat((DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ "%U"
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
+ ((DBusPyDict *)obj)->signature);
+ }
+#else
if (DBusPyDict_Check(obj) &&
PyBytes_Check(((DBusPyDict *)obj)->signature))
{
@@ -345,6 +404,7 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr)
DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
sig);
}
+#endif
if (!PyDict_Next(obj, &pos, &key, &value)) {
/* No items, so fail. Or should we guess "a{vv}"? */
PyErr_SetString(PyExc_ValueError, "Unable to guess signature "
@@ -354,19 +414,27 @@ _signature_string_from_pyobject(PyObject *obj, long *variant_level_ptr)
keysig = _signature_string_from_pyobject(key, NULL);
valuesig = _signature_string_from_pyobject(value, NULL);
if (keysig && valuesig) {
+#ifdef PY3
+ ret = PyUnicode_FromFormat((DBUS_TYPE_ARRAY_AS_STRING
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ "%U%U"
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
+ keysig, valuesig);
+#else
ret = PyBytes_FromFormat((DBUS_TYPE_ARRAY_AS_STRING
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
"%s%s"
DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
PyBytes_AS_STRING(keysig),
PyBytes_AS_STRING(valuesig));
+#endif
}
Py_CLEAR(keysig);
Py_CLEAR(valuesig);
return ret;
}
else {
- PyErr_Format(PyExc_TypeError, "Don't know how which D-Bus type "
+ PyErr_Format(PyExc_TypeError, "Don't know which D-Bus type "
"to use to encode type \"%s\"",
Py_TYPE(obj)->tp_name);
return NULL;
@@ -411,6 +479,20 @@ dbus_py_Message_guess_signature(PyObject *unused UNUSED, PyObject *args)
DBG("%s", "Message_guess_signature: failed");
return NULL;
}
+ if (PyUnicode_Check(tmp)) {
+ PyObject *as_bytes = PyUnicode_AsUTF8String(tmp);
+ Py_CLEAR(tmp);
+ if (!as_bytes)
+ return NULL;
+ if (PyBytes_GET_SIZE(as_bytes) < 2) {
+ PyErr_SetString(PyExc_RuntimeError, "Internal error: "
+ "_signature_string_from_pyobject returned "
+ "a bad result");
+ Py_CLEAR(as_bytes);
+ return NULL;
+ }
+ tmp = as_bytes;
+ }
if (!PyBytes_Check(tmp) || PyBytes_GET_SIZE(tmp) < 2) {
PyErr_SetString(PyExc_RuntimeError, "Internal error: "
"_signature_string_from_pyobject returned "
@@ -421,8 +503,6 @@ dbus_py_Message_guess_signature(PyObject *unused UNUSED, PyObject *args)
ret = PyObject_CallFunction((PyObject *)&DBusPySignature_Type, "(s#)",
PyBytes_AS_STRING(tmp) + 1,
PyBytes_GET_SIZE(tmp) - 2);
- DBG("Message_guess_signature: returning Signature at %p \"%s\"", ret,
- ret ? PyBytes_AS_STRING(ret) : "(NULL)");
Py_CLEAR(tmp);
return ret;
}
@@ -514,6 +594,21 @@ _message_iter_append_byte(DBusMessageIter *appender, PyObject *obj)
}
y = *(unsigned char *)PyBytes_AS_STRING(obj);
}
+ else if (PyUnicode_Check(obj)) {
+ PyObject *obj_as_bytes = PyUnicode_AsUTF8String(obj);
+
+ if (!obj_as_bytes)
+ return -1;
+ if (PyBytes_GET_SIZE(obj_as_bytes) != 1) {
+ PyErr_Format(PyExc_ValueError, "Expected a string of "
+ "length 1 byte, but found %d bytes",
+ (int)PyBytes_GET_SIZE(obj_as_bytes));
+ Py_CLEAR(obj_as_bytes);
+ return -1;
+ }
+ y = *(unsigned char *)PyBytes_AS_STRING(obj_as_bytes);
+ Py_CLEAR(obj_as_bytes);
+ }
else {
long i = PyLong_AsLong(obj);
@@ -552,7 +647,12 @@ _message_iter_append_unixfd(DBusMessageIter *appender, PyObject *obj)
int fd;
long original_fd;
- if (PyLong_Check(obj) || PyInt_Check(obj)) {
+ if (PyLong_Check(obj)
+#ifndef PY3
+ || PyInt_Check(obj)
+#endif
+ )
+ {
original_fd = PyLong_AsLong(obj);
if (original_fd == -1 && PyErr_Occurred())
return -1;
@@ -829,8 +929,18 @@ _message_iter_append_variant(DBusMessageIter *appender, PyObject *obj)
obj_sig = _signature_string_from_pyobject(obj, &variant_level);
if (!obj_sig) return -1;
+ if (PyUnicode_Check(obj_sig)) {
+ PyObject *obj_sig_as_bytes = PyUnicode_AsUTF8String(obj_sig);
+ Py_CLEAR(obj_sig);
+ if (!obj_sig_as_bytes)
+ return -1;
+ obj_sig = obj_sig_as_bytes;
+ }
obj_sig_str = PyBytes_AsString(obj_sig);
- if (!obj_sig_str) return -1;
+ if (!obj_sig_str) {
+ Py_CLEAR(obj_sig);
+ return -1;
+ }
if (variant_level < 1) {
variant_level = 1;
@@ -1124,6 +1234,17 @@ dbus_py_Message_append(Message *self, PyObject *args, PyObject *kwargs)
DBG("%s", "No signature for message, guessing...");
signature_obj = dbus_py_Message_guess_signature(NULL, args);
if (!signature_obj) return NULL;
+ if (PyUnicode_Check(signature_obj)) {
+ PyObject *signature_as_bytes;
+ signature_as_bytes = PyUnicode_AsUTF8String(signature_obj);
+ Py_CLEAR(signature_obj);
+ if (!signature_as_bytes)
+ return NULL;
+ signature_obj = signature_as_bytes;
+ }
+ else {
+ assert(PyBytes_Check(signature_obj));
+ }
signature = PyBytes_AS_STRING(signature_obj);
}
/* from here onwards, you have to do a goto rather than returning NULL