diff options
author | Barry Warsaw <barry@python.org> | 2011-12-15 06:57:21 -0500 |
---|---|---|
committer | Barry Warsaw <barry@python.org> | 2011-12-15 06:57:21 -0500 |
commit | 4c1c2eade1c5b383adad94a7a4fd6553873fecf0 (patch) | |
tree | b9e0f45fc19539bcaddff69e661bf0c5d21bab5a /_dbus_bindings/message-append.c | |
parent | 667082d0b4aef9c438a2e7fec89614b5b8ef960a (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.c | 195 |
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 |